• hdu 4598 差分约束


    思路:首先就是判断是否有奇环,若存在奇环,则输出No。

    然后用差分约束找是否符合条件。

    对于e(i,j)属于E,并且假设顶点v[i]为正数,那么v[i]-v[j]>=T--->v[j]-v[i]<=-T;

    对于e(i,j)不属于E,并且假设顶点v[i]为正数,那么v[i]-v[j]<=T-1;

    以0号点为参照点,若果v[i]为负数,那么v[0]-v[i]<=T-1;  v[i]-v[0]<=0;

    若果v[i]为正数,那么v[i]-v[0]<=T-1;  v[0]-v[i]<=0;

    有上述条件即可建边求最短路,若果存在负圈,那么就是不存在。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define Maxn 1010
    #define Maxm Maxn*Maxn
    #define inf 100000000
    #define T 400
    using namespace std;
    int head[Maxn],vi[Maxn],col[Maxn],map[Maxn][Maxn],e,n,cnt[Maxn],dis[Maxn];
    void init()
    {
        memset(head,-1,sizeof(head));
        memset(vi,0,sizeof(vi));
        memset(map,0,sizeof(map));
        memset(col,-1,sizeof(col));
        e=0;
    }
    struct Edge{
        int u,next,v,val;
    }edge[Maxm];
    void addedge(int u, int v)
    {
        edge[e].u=u;edge[e].v=v;edge[e].next=head[u];head[u]=e++;
        edge[e].v=u;edge[e].u=v;edge[e].next=head[v];head[v]=e++;
    }
    void add(int u,int v,int val)
    {
        edge[e].u=u,edge[e].v=v,edge[e].val=val,edge[e].next=head[u],head[u]=e++;
    }
    void find(int u,int c)
    {
        int i,j,temp;
        vi[u]=1;
        for(i=head[u];i!=-1;i=edge[i].next){
            temp=edge[i].v;
            if(col[temp]==-1){
                col[temp]=c;
                find(temp,c^1);
            }
        }
    }
    int spfa()
    {
        int i,j,v,u;
        queue<int> q;
        memset(cnt,0,sizeof(cnt));
        memset(vi,0,sizeof(vi));
        for(i=0;i<=n;i++){
            dis[i]=inf;
        }
        dis[0]=0;
        q.push(0);
        while(!q.empty()){
            int u=q.front();
            q.pop();
            vi[u]=0;
            for(i=head[u];i!=-1;i=edge[i].next){
                v=edge[i].v;
                if(dis[v]>dis[u]+edge[i].val){
                    dis[v]=dis[u]+edge[i].val;
                    cnt[v]++;
                    if(cnt[v]>n) return 0;
                    if(!vi[v]){
                        q.push(v);
                        vi[v]=1;
                    }
                }
            }
        }
        return 1;
    }
    int solve()
    {
        int i,j,u,v;
        for(i=1;i<=n;i++)  if(!vi[i]) find(i,0);
        for(i=0;i<e;i++) if(col[edge[i].u]==col[edge[i].v]) return 0;
        memset(head,-1,sizeof(head));
        e=0;
        for(i=1;i<=n;i++){
            for(j=i+1;j<=n;j++){
                if(!map[i][j]&&col[i]==col[j]) continue;
                u=i,v=j;
                if(col[u]==0)
                    swap(u,v);
                if(map[u][v])
                    add(u,v,-T);
                else
                    add(v,u,T-1);
            }
            if(col[i]==0){
                add(i,0,T-1);
                add(0,i,0);
            }
            else{
                add(0,i,T-1);
                add(i,0,0);
            }
        }
        return spfa();
    }
    int main()
    {
        int t,i,j;
        char str[310];
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            init();
            for(i=1;i<=n;i++){
                scanf("%s",&str);
                for(j=0;j<n;j++){
                    if(str[j]=='1'&&!map[i][j+1]){
                        addedge(i,j+1);
                        map[i][j+1]=map[j+1][i]=1;
                    }
                }
            }
            if(!solve())
                printf("No
    ");
            else
                printf("Yes
    ");
        }
        return 0;
    }
  • 相关阅读:
    函数指针和指针函数和回调函数以及函数指针数组
    C语言中的结构体,结构体数组
    linux中的shell脚本编程
    回车和换行在linux下和windows下
    内存的段式管理和页式管理,逻辑地址-虚拟地址-物理地址
    [CSAPP-II] 链接[符号解析和重定位] 静态链接 动态链接 动态链接接口
    c语言中函数调用的本质从汇编角度分析
    运算符优先级
    Redis实战经验及使用场景
    RESTful API 设计最佳实践【转】
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3279996.html
Copyright © 2020-2023  润新知