zoukankan      html  css  js  c++  java
  • 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
    ",t);
            else printf("Case #%d: No
    ",t);
        }
        return 0;
    }
  • 相关阅读:
    mssql分页原理及效率分析
    [ActiveX]使用VS2010创建MFC ActiveX工程项目
    Study notes for Discrete Probability Distribution
    oracle存储过程异常捕获
    (Python学习9)Python虚拟机中的一般表达式
    用Arduino做一个可视化网络威胁级别指示器!
    iOS上线项目源码分享
    android实习程序6——拨号通话
    评价等级使用的五星选择,包含半星的选择
    AJAX实现无刷新验证用户名
  • 原文地址:https://www.cnblogs.com/zzyer/p/8679025.html
Copyright © 2011-2022 走看看