• poj 1698 Alice's Chance 拆点最大流


    将星期拆点,符合条件的连边,最后统计汇点流量是否满即可了,注意结点编号。


    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<queue>
    #include<vector>
    #include<string>
    #define eps  1e-12
    #define INF   0x7fffffff
    #define maxn 1000
    using namespace std;
    int n,m;
    int en;
    int st,ed;	//源点和汇点
    int dis[maxn] ;//dis[i],表示  到 原点  s 的 层数
    int que[999999];
    int can[55][11];
    struct edge
    {
    	int to,c,next;
    };
    edge e[999999];
    int head[maxn];
    void add(int a,int b,int c)
    {
    	e[en].to=b;
    	e[en].c=c;
    	e[en].next=head[a];
    	head[a]=en++;
    	e[en].to=a;
    	e[en].c=0;
    	e[en].next=head[b];
    	head[b]=en++;
    }
    int bfs()
    {
        memset(dis,-1,sizeof(dis));
        dis[st]=0;
        int front=0,rear=0;
        que[rear++]=st;
        while(front<rear)
        {
            int j=que[front++];
            for(int k=head[j];k!=-1;k=e[k].next)
            {
                int i=e[k].to;
    			if(dis[i]==-1&&e[k].c)
                {
                    dis[i] = dis[j]+ 1 ;
                    que[rear++]=i;
                    if(i==ed) return true;
                }
            }
        }
        return false;
    }
    int dfs(int x,int mx)
    {
        int i,a;
        if(x==ed) return mx ;
        int ret=0;
        for(int k=head[x];k!=-1&&ret<mx;k=e[k].next)
        {
            if(e[k].c&&dis[e[k].to]==dis[x]+1)
            {
                int dd=dfs(e[k].to,min(e[k].c,mx-ret));
                e[k].c-=dd;
                e[k^1].c+=dd;
                ret+=dd;
            }
        }
        if(!ret) dis[x]=-1;
        return ret;
    }
    void init()
    {
        en=0;
    	st=0;     //源
        ed=20+50*7+100;     //汇
    	memset(head,-1,sizeof(head));
    }
    void build()
    {
        for(int i=1;i<=n;i++) add(i,ed,can[i][8]);
        for(int i=n+1;i<=n+350;i++) add(st,i,1);
        for(int i=1;i<=n;i++)
        {
            for(int j=0,id=n+1;j<can[i][9];j++)   //第几周
            {
                for(int t=1;t<=7;t++,id++)
                {
                    if(can[i][t]) add(id,i,1);
                }
            }
        }
    }
    int dinic()
    {
        int tmp=0;
        int maxflow=0;
        while(bfs())
        {
            while(tmp=dfs(st,INF)) maxflow+=tmp;
        }
        return maxflow;
    }
    
    int main()
    {
        int cas;
        int ans;
        scanf("%d",&cas);
        while(cas--)
        {
            ans=0;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=9;j++)
                {
                    scanf("%d",&can[i][j]);
                }
                ans+=can[i][8];
            }
            init();
            build();
       //     cout<<dinic()<<endl;
            printf("%s
    ",dinic()==ans?"Yes":"No");
        }
    }
    


  • 相关阅读:
    Fitness
    【代码优化】Unity查漏补缺
    Fitness
    MonoBehaviour生命周期与对象数据池应用
    Fitness
    点、向量、方向在局部与世界坐标系转换的对比
    在企业运营中的感触
    技术杂想2015年夏天
    Heimich manoeuvre 海姆利克氏操作
    徒手CPR心脏复苏
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4087819.html
Copyright © 2020-2023  润新知