codeforces472D Design Tutorial: Inverse the Problem 最小生成树+dfs

来源:互联网 发布:网游之武知我道笔趣阁 编辑:程序博客网 时间:2024/05/26 16:00

题意:给定一个n*n的矩阵,矩阵第(i,j)位表示i到j的距离,问是否能构成树。

思路:一开始想用flyod作n次转移得两点之间的最短距离,然后跟原矩阵比较,如果不相同不能构成。只是复杂度为O(n^3),不行。

其实因为是构成一棵树,所构成的MST对应的矩阵应该即为输入矩阵,MST对应的矩阵用dfs求得即可。有一个wa点就是因为输入的

权值可能全为零,对于n=1的时候应特判输入YES,不然输NO。详见代码:

// file name: codeforces472D.cpp //// author: kereo //// create time:  2014年09月29日 星期一 13时02分25秒 ////***********************************//#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<set>#include<map>#include<vector>#include<stack>#include<cmath>#include<string>#include<algorithm>using namespace std;typedef long long ll;const int MAXN=2000+100;const int inf=0x3fffffff;const int mod=1000000000+7;#define L(x) (x<<1)#define R(x) (x<<1|1)int n,edge_cnt;int head[MAXN],fa[MAXN],vis[MAXN],mp[MAXN][MAXN],d[MAXN][MAXN];struct Edge{int u,v,w;int next;}edge[MAXN*MAXN],edge1[MAXN*MAXN];bool cmp(Edge a,Edge b){return a.w<b.w;}void init(){edge_cnt=0;memset(vis,0,sizeof(vis));memset(head,-1,sizeof(head));for(int i=1;i<=n;i++)fa[i]=i;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&mp[i][j]);}int findset(int x){return fa[x] == x ? x : fa[x]=findset(fa[x]);}void addedge(int u,int v,int w){edge[edge_cnt].u=u; edge[edge_cnt].v=v; edge[edge_cnt].w=w;edge[edge_cnt].next=head[u];head[u]=edge_cnt++;}void dfs(int s,int u,int fa,int w){d[s][u]=w;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(v == fa)continue;if(vis[v]) continue;vis[v]=1;dfs(s,v,u,w+edge[i].w);vis[v]=0;}}int main(){while(~scanf("%d",&n)){init();int flag=1;for(int i=1;i<=n;i++){for(int j=i;j<=n;j++){if((i == j && mp[i][j]!=0) || mp[i][j]!=mp[j][i]){flag=0;break;}}if(!flag)break;}if(!flag){printf("NO\n");continue;}int cnt=0;for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++) if(mp[i][j])edge1[cnt].u=i,edge1[cnt].v=j,edge1[cnt++].w=mp[i][j];if(cnt == 0){if(n == 1)printf("YES\n");elseprintf("NO\n");continue;}sort(edge1,edge1+cnt,cmp);for(int i=0;i<cnt;i++){int fx=findset(edge1[i].u);int fy=findset(edge1[i].v);if(fx == fy)continue;fa[fx]=fy;addedge(edge1[i].u,edge1[i].v,edge1[i].w);addedge(edge1[i].v,edge1[i].u,edge1[i].w);}for(int i=1;i<=n;i++){vis[i]=1;dfs(i,i,-1,0);vis[i]=0;}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)if(mp[i][j]!=d[i][j]){flag=0;break;}if(!flag)break;}if(flag)printf("YES\n");else printf("NO\n");}return 0;}


0 0
原创粉丝点击