BZOJ 3332

题解:给边赋上权值,然后求最大生成树,如果不符合那就无解

证明:留坑

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxN=1009;
const int maxM=300009;
const int oo=1000000000;

int TT;
int n,m;
int f[maxN][maxN];
struct Edge{
    int u,v,ed;
}edges[maxM];
bool mycmp(const Edge &E1,const Edge &E2){
    return E1.ed>E2.ed;
}

int father[maxN];
int Getf(int x){
    if(father[x]==x)return x;
    return father[x]=Getf(father[x]);
}
void Unionn(int x,int y){
    int fx=Getf(x);
    int fy=Getf(y);
    if(fx!=fy){
        father[fx]=fy;
    }
}

int cntedge=0;
int head[maxN]={0};
int to[maxN<<1],nex[maxN<<1],dist[maxN<<1];
void Addedge(int x,int y,int z){
    nex[++cntedge]=head[x];
    to[cntedge]=y;
    dist[cntedge]=z;
    head[x]=cntedge;
}

int fdist[maxN];
void Dfs(int x,int fa){
    for(int i=head[x];i;i=nex[i]){
        if(to[i]==fa)continue;
        fdist[to[i]]=min(fdist[x],dist[i]);
        Dfs(to[i],x);
    }
}

void Myinit(){
    cntedge=0;
    memset(head,0,sizeof(head));
}
int rd(){
    int r=0,k=1;
    char c=getchar();
    for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
    for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
    return r*k;
}

int main(){
    scanf("%d",&TT);
    for(int t=1;t<=TT;++t){
        Myinit();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;++i)scanf("%d%d",&edges[i].u,&edges[i].v);
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j){
                scanf("%d",&f[i][j]);
            }
        }
        for(int i=1;i<=m;++i){
            int u=edges[i].u;
            int v=edges[i].v;
            edges[i].ed=f[u][v];
        }
        sort(edges+1,edges+1+m,mycmp);
        for(int i=1;i<=n;++i)father[i]=i;
        for(int i=1;i<=m;++i){
            int u=edges[i].u,v=edges[i].v,z=edges[i].ed;
            if(Getf(u)==Getf(v))continue;
            Unionn(u,v);
            Addedge(u,v,z);
            Addedge(v,u,z);
        }
        int fla=1;
        for(int u=1;u<=n;++u){
            fdist[u]=oo;
            Dfs(u,0);
            for(int v=1;v<=n;++v){
                if(u==v)continue;
                if(Getf(u)!=Getf(v)){
                    if(f[u][v]!=-1){
                        fla=0;break;
                    }
                }else{
                    if(f[u][v]!=fdist[v]){
                        fla=0;break;
                    }
                }
            }
            if(!fla)break;
        }
        if(fla)printf("Case #%d: Yes\n",t);
        else printf("Case #%d: No\n",t);
    }
    return 0;
}

 

posted @ 2018-03-30 22:32  ws_zzy  阅读(193)  评论(0编辑  收藏  举报