UVA 125 统计路径条数 FLOYD
这道题目折腾了我一个下午,本来我的初步打算是用SPFA(),进行搜索,枚举出发点,看看能到达某个点多少次,就是出发点到该点的路径数,如果出现环,则置为-1,关键在于这个判环过程,如果简单只找到某个点是为环路上一点,即访问它的次数超过了所有点的点数目,这样就会出问题,因为它会影响其他点,下一步是否将它进入队列,如果进入,会造成无限循环,不进的话,根本得不出正确结果,后来我写了个judge函数,判断该点是否还能影响其他点,这样的话,因为要全图搜索,又TLE了。。。
没办法,只好换了网站说的FLOYD;
这是错误的代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int u[1000],v[1000],w[1000],nt[1000],ft[50],vis[50],d[50],num[50]; int n,e,maxn,sta[1000],test[1000]; void addedge(int a,int b) { u[e]=a; v[e]=b; w[e]=0; nt[e]=ft[a]; ft[a]=e++; } bool judge(int x) { int j,top=0; memset(vis,0,sizeof vis); //return dfs(x); test[top++]=x; vis[x]=1; while (top) { int nx=test[--top]; if (num[nx]>=0) return 1; for (j=ft[nx];j>=0;j=nt[j]) { int ns=v[j]; if (!vis[ns]) { test[top++]=ns; vis[ns]=1; } } } return 0; } void spfa(int root) { int i,j,top=0; memset(vis,0,sizeof vis); memset(num,0,sizeof num); sta[top++]=root; vis[root]=1; while (top) { int x=sta[--top]; //cout<<x<<" pp "<<endl; vis[x]=0; for (i=ft[x];i>=0;i=nt[i]) { int nx=v[i]; //if (nx==x) continue; if (num[nx]>=0) num[nx]++; if (num[nx]>maxn+1) { num[nx]=-1; } //cout<<nx<<" nx num "<<num[nx]<<endl; //int temp; //cin>>temp; if (judge(nx)) { sta[top++]=nx; vis[nx]=1; } } } } int main() { int cnt=0,i,j; while (scanf("%d",&n)!=EOF) { memset(ft,-1,sizeof ft); maxn=e=0; int a,b; for (i=1;i<=n;i++) { scanf("%d%d",&a,&b); addedge(a,b); maxn=maxn<a? a:maxn; maxn=maxn<b? b:maxn; } printf("matrix for city %d\n",cnt++); for (i=0;i<=maxn;i++) { //cout<<i<<" pp "<<endl; spfa(i); for (j=0;j<=maxn;j++) { printf("%d",num[j]); if (j<maxn) putchar(' '); } putchar('\n'); } } return 0; }
这是AC的代码
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int g[50][50]; int d[50][50],num[50][50]; int n,maxn; void init() { for (int i=0; i<50; i++) { for (int j=0; j<50; j++) { if (i==j) g[i][j]=0; else g[i][j]=-1; d[i][j]=0; } } } int main() { int i,j,k,cnt=0; while (scanf("%d",&n)!=EOF) { init(); int a,b; maxn=0; memset(num,0,sizeof num); for (i=1; i<=n; i++) { scanf("%d%d",&a,&b); g[a][b]=1; num[a][b]=1; maxn=maxn>a ? maxn:a; maxn=maxn>b ? maxn:b; } for (i=0; i<=maxn; i++) { for (j=0; j<=maxn; j++) { for (k=0; k<=maxn; k++) { //if (j==k) continue; if (num[j][i] && num[i][k]) num[j][k]+=num[j][i]*num[i][k]; } } } for (i=0;i<=maxn;i++) { if (num[i][i]>0) { for (j=0;j<=maxn;j++) { for (k=0;k<=maxn;k++) { if (num[j][i] && num[i][k]) num[j][k]=-1; } } } } printf("matrix for city %d\n",cnt++); for (i=0;i<=maxn;i++) { for (j=0;j<=maxn;j++) { printf("%d",num[i][j]); if (j<maxn) putchar(' '); } putchar('\n'); } } return 0; }
FLOYD用这道题目原理很简单,就是因为它能算出所有点点的距离,因此用它来计算点点之间的路径数也是理所应当的可以。。关键在于成环的判断,一旦有某点num[k][k]>0,则该点必定在环内。。因此进行置-1操作。最后打印结果即可。