题解:
首先只有存在的路有可能有值
然后在存储矩阵的同时对于本来就有边的情况直接存下来这条边的值
然后跑一次最大生成树
在最大生成树的同时就可以求出矩阵的信息。
代码:
#include<bits/stdc++.h> #define clr(x) memset(x,0,sizeof(x)) using namespace std; const int N=1e3+5; int t,n,m,sta,fin,mapy[N][N],mapy2[N][N],fa[N],son[N][N],cnt,ans; struct node { int sta,fin,wor; }roa[N*300]; int read() { int x=0; char ch=getchar(); bool positive=1; for (;!isdigit(ch);ch=getchar()) if (ch=='-')positive=0; for (;isdigit(ch);ch=getchar())x=x*10+ch-'0'; return positive?x:-x; } void addedge(int sta,int fin) { mapy[sta][fin]=read(); roa[++cnt].sta=sta; roa[cnt].fin=fin; roa[cnt].wor=mapy[sta][fin]; } int fath(int u) { return fa[u]=(fa[u]==u?u:fath(fa[u])); } void check(int sta,int fin) { if(sta==fin&&mapy[sta][fin]!=0)ans=1; if(sta>fin&&mapy[sta][fin]!=mapy[fin][sta])ans=1; } void init() { n=read();m=read();cnt=0; clr(mapy);clr(mapy2);clr(fa); clr(son);clr(roa); for(int i=1;i<=n;i++)fa[i]=son[i][++son[i][0]]=i; for(int i=1;i<=m;i++) { sta=read();fin=read(); if(sta>fin)swap(sta,fin); mapy[sta][fin]=1; } ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(mapy[i][j])addedge(i,j); else mapy[i][j]=read(); check(i,j); } } bool cmp(node x,node y) { return x.wor>y.wor; } void unio(int u) { int fa1=fa[roa[u].sta],fa2=fa[roa[u].fin]; fa[fa1]=fa2; for(int i=1;i<=son[fa1][0];i++) for(int j=1;j<=son[fa2][0];j++) mapy2[son[fa1][i]][son[fa2][j]]= mapy2[son[fa2][j]][son[fa1][i]]=roa[u].wor; for(int i=1;i<=son[fa1][0];i++)son[fa2][++son[fa2][0]]=son[fa1][i]; } int work(int cur) { printf("Case #%d: ",cur); if(ans)return ans; sort(roa+1,roa+m+1,cmp); for(int i=1;i<=m;i++) { if(fath(roa[i].sta)==fath(roa[i].fin))continue; unio(i); } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(fath(i)!=fath(j)){if(mapy[i][j]!=-1)ans=1;} else if(mapy2[i][j]!=mapy[i][j])ans=1; } return ans; } int main() { t=read(); for (int i=1;i<=t;i++) { init(); if(work(i))puts("No"); else puts("Yes"); } return 0; }