zoukankan      html  css  js  c++  java
  • hdu 4888 Redraw Beautiful Drawings(最大流,判环)

    http://acm.hdu.edu.cn/showproblem.php?pid=4888


    加入一个源点与汇点,建图例如以下

    1. 源点 -> 每一行相应的点,流量限制为该行的和

    2. 每一行相应的点 -> 每一列相应的点,流量限制为 K

    3. 每一列相应的点 -> 汇点,流量限制为该列的和

    求一遍最大流,若最大流与矩阵之和相等,说明有解,否则无解。推断唯一解,是推断残量网络中是否存在一个长度大于2的环。若存在说明有多解,否则有唯一解,解就是每条边行i->列j的流量。


    #include <stdio.h>
    #include <iostream>
    #include <map>
    #include <set>
    #include <stack>
    #include <vector>
    #include <math.h>
    #include <string.h>
    #include <queue>
    #include <string>
    #include <stdlib.h>
    #include <algorithm>
    #define LL long long
    #define _LL __int64
    #define eps 1e-12
    #define PI acos(-1.0)
    #define C 240
    #define S 20
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    
    const int maxn = 810;
    const int maxm = 160000+810;
    
    struct node
    {
        int u,v,w,next;
    } edge[maxm << 1];
    
    int cnt,head[maxn];
    int n,m,k,s,t;
    int nn[410],mm[410];
    int maxflow;
    int vis[maxn];
    int dis[maxn];
    
    void init()
    {
        cnt = 0;
        memset(head,-1,sizeof(head));
    }
    
    void add(int u, int v, int f)
    {
        edge[cnt] = (struct node){u,v,f,head[u]};
        head[u] = cnt++;
    
        edge[cnt] = (struct node){v,u,0,head[v]};
        head[v] = cnt++;
    }
    
    bool bfs()
    {
        queue<int>que;
        while(!que.empty()) que.pop();
        memset(dis,-1,sizeof(dis));
        dis[s] = 0;
        que.push(s);
    
        while(!que.empty())
        {
            int u = que.front();
            que.pop();
    
            for(int i = head[u]; i != -1; i = edge[i].next)
            {
                int v = edge[i].v;
                if(dis[v] == -1 && edge[i].w)
                {
                    dis[v] = dis[u]+1;
                    que.push(v);
                }
            }
        }
        if(dis[t] == -1)
            return false;
        return true;
    }
    
    int dfs(int u, int delta)
    {
        if(u == t || delta == 0) return delta;
        int dd;
        int ret = 0;
        for(int i = head[u]; i != -1 && delta; i = edge[i].next)
        {
            if(dis[edge[i].v] == dis[u]+1 && (dd = dfs(edge[i].v,min(delta,edge[i].w))))
            {
                edge[i].w -= dd;
                edge[i^1].w += dd;
                delta -= dd;
                ret += dd;
                if(delta == 0)
                    return ret;
            }
        }
    	dis[u] = -1;
    	return ret;
    }
    
    int Dinic()
    {
        int ret = 0;
        while(bfs())
        {
            ret += dfs(s,INF);
        }
        return ret;
    }
    
    int dfs_1(int u,int fa)
    {
        for(int i=head[u]; i!=-1; i=edge[i].next)
        {
            if(i==(fa^1)) continue;
            if(edge[i].w)
            {
                if(vis[edge[i].v]) return 1;
                vis[edge[i].v]=1;
                if(dfs_1(edge[i].v,i)) return 1;
                vis[edge[i].v]=0;
            }
        }
        return 0;
    }
    
    void putmat()
    {
    	int f[410][410];
    	printf("Unique
    ");
    	for(int u = 1; u <= n; u++)
    	{
    		for(int i = head[u]; i != -1; i = edge[i].next)
    		{
    			int v = edge[i].v;
    			if(v > n && v <= n+m)
    				f[u][v-n] = k - edge[i].w;
    		}
    	}
    	for(int i = 1; i <= n; i++)
    	{
    		for(int j = 1; j < m; j++)
    			printf("%d ",f[i][j]);
    		printf("%d
    ",f[i][m]);
    	}
    }
    
    int main()
    {
        while(~scanf("%d %d %d",&n,&m,&k))
        {
        	init();
            s = 0;
            t = n+m+1;
            int sum1 = 0;
            int sum2 = 0;
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&nn[i]);
                add(s,i,nn[i]);
                sum1 += nn[i];
    			for(int j = 1; j <= m; j++)
    				add(i,j+n,k);
            }
    
            for(int i = 1; i <= m; i++)
            {
                scanf("%d",&mm[i]);
                add(i+n,t,mm[i]);
                sum2 += mm[i];
            }
    
            if(sum1 != sum2)
            {
                printf("Impossible
    ");
            }
    
    		else
    		{
    			maxflow = Dinic();
    
    			if(maxflow != sum1)
    			{
    				printf("Impossible
    ");
    			}
    			else
    			{
    				int flag = 0;
    				memset(vis,0,sizeof(vis));
    				for(int i = 1; i <= n; i++)
    				{
    					if(dfs_1(i,-1))
    					{
    						flag = 1;
    						break;
    					}
    				}
    				if(flag == 1)
    					printf("Not Unique
    ");
    
    				else
    					putmat();
    			}
    		}
        }
        return 0;
    }
    





  • 相关阅读:
    CSS学习笔记-盒子阴影及文字阴影
    CSS学习笔记-2D转换模块
    CSS学习笔记-过度模块-编写过渡效果
    CSS学习笔记-过渡模块
    Unity3D_Transform_位置、角度、缩放及其他
    微信小程序实现生成画报并且实现下载功能
    前端知识点
    vue导出excel表格用到的两个文件
    react 的高阶组件
    代理的配置
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6854807.html
Copyright © 2011-2022 走看看