UVA 10917
Posted TSOI_Vergil
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 10917相关的知识,希望对你有一定的参考价值。
这道题的意思是,起点是1,终点是2,从1走到2,对于一条边(a,b),只有当存在一条从b出发的到2的路径长小于任何从a出发的路径长,我们才能走,问走到2的方案数。首先我们考虑,如果存在一条b出发的路径,那一定是b到2的最短路,而从a出发到2的路径的最小值也是a到2的最短路,那么我们可以以2为起点做一遍最短路,然后我们枚举边,如果对于一条边(u,v),dis[u]>dis[v],我们就在新图中加入u-->v,可以知道新图是一个DAG,因为如果成环的话,我们可以推出矛盾,这样我们在DAG上DP算方案数即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 1005
#define maxm 200005
int last[maxn][2],pre[maxm][2],other[maxm][2],len[maxm][2];
int dis[maxn],n,m,l,que[maxm+5],rd[maxn],dp[maxn];
bool vis[maxn];
void connect(int x,int y,int z,int opt)
l++;
pre[l][opt]=last[x][opt];
last[x][opt]=l;
other[l][opt]=y;
len[l][opt]=z;
void spfa(void)
int h=0,t=1;
que[1]=2;
while (h!=t)
h=h%maxm+1;
int u=que[h];vis[u]=0;
for (int p=last[u][0];p;p=pre[p][0])
int v=other[p][0];
if (dis[v]>dis[u]+len[p][0])
dis[v]=dis[u]+len[p][0];
if (!vis[v])
t=t%maxm+1;
que[t]=v;
vis[v]=1;
int main()
while (1)
scanf("%d",&n);
if (n==0) break;
scanf("%d",&m);
memset(last,0,sizeof last);l=0;
memset(dis,127,sizeof dis);dis[2]=0;
memset(dp,0,sizeof dp);
memset(rd,0,sizeof rd);
for (int i=1;i<=m;i++)
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
connect(a,b,c,0);
connect(b,a,c,0);
spfa();
for (int i=1;i<=n;i++)
for (int p=last[i][0];p;p=pre[p][0])
int v=other[p][0];
if (dis[v]<dis[i])
connect(i,v,0,1);
rd[v]++;
int h=1,t=0;
for (int i=1;i<=n;i++)
if (rd[i]==0) que[++t]=i;
while (h<=t)
int u=que[h];h++;
for (int p=last[u][1];p;p=pre[p][1])
int v=other[p][1];
rd[v]--;
if (rd[v]==0) que[++t]=v;
dp[2]=1;
for (int i=n;i>=1;i--)
int u=que[i];
for (int p=last[u][1];p;p=pre[p][1])
int v=other[p][1];
dp[u]+=dp[v];
printf("%d\\n",dp[1]);
return 0;
以上是关于UVA 10917的主要内容,如果未能解决你的问题,请参考以下文章
Uva 10917 Walk Through the Forest
UVA10917 Walk Through the Forest
G - Walk Through the Forest (UVA - 10917)