zoukankan      html  css  js  c++  java
  • HDU 4888 Redraw Beautiful Drawings

    网络流。

    $s$向每一个$r[i]$连边,容量为$r[i]$。

    每一个$r[i]$向每一个$c[j]$连边,容量为$k$。

    每一个$c[j]$向$t$连边容量为$c[j]$。

    跑最大流,中间每一条边上的容量就是那一个格子所填的数字。

    唯一性判定:如果残留网络上有环,那么不唯一。

    #include<map>
    #include<set>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    #define ms(x,y) memset(x,y,sizeof(x))
    #define rep(i,j,k) for(int i=j;i<=k;i++)
    #define per(i,j,k) for(int i=j;i>=k;i--)
    #define loop(i,j,k) for (int i=j;i!=-1;i=k[i])
    #define inone(x) scanf("%d",&x)
    #define intwo(x,y) scanf("%d%d",&x,&y)
    #define inthr(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define infou(x,y,z,p) scanf("%d%d%d%d",&x,&y,&z,&p)
    #define lson x<<1,l,mid
    #define rson x<<1|1,mid+1,r
    #define mp(i,j) make_pair(i,j)
    #define ft first
    #define sd second
    typedef long long LL;
    typedef pair<int, int> pii;
    const int low(int x) { return x&-x; }
    const int INF = 0x7FFFFFFF;
    const int mod = 1e9 + 7;
    const int N = 4e5 + 10;
    const double eps = 1e-10;
    
    int n,m,k;
    
    const int maxn = 1000 + 10;
    struct Edge
    {
        int from, to, cap, flow;
        Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){}
    };
    vector<Edge>edges;
    vector<int>G[maxn],GG[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn],q[maxn];
    int s, t,FF,sz;
    
    void init()
    {
        for (int i = 0; i < maxn; i++) G[i].clear();
        for (int i = 0; i < maxn; i++) GG[i].clear();
    
        edges.clear();
    }
    
    void AddEdge(int from, int to, int cap)
    {
        edges.push_back(Edge(from, to, cap, 0));
        edges.push_back(Edge(to, from, 0, 0));
        int w = edges.size();
        G[from].push_back(w - 2);
        G[to].push_back(w - 1);
    }
    
    bool BFS()
    {
        memset(vis, 0, sizeof(vis));
        queue<int>Q;
        Q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!Q.empty())
        {
            int x = Q.front();
            Q.pop();
            for (int i = 0; i<G[x].size(); i++)
            {
                Edge e = edges[G[x][i]];
                if (!vis[e.to] && e.cap>e.flow)
                {
                    vis[e.to] = 1;
                    d[e.to] = d[x] + 1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    
    int DFS(int x, int a)
    {
        if (x == t || a == 0)
            return a;
        int flow = 0, f;
        for (int &i = cur[x]; i<G[x].size(); i++)
        {
            Edge e = edges[G[x][i]];
            if (d[x]+1 == d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
            {
                edges[G[x][i]].flow+=f;
                edges[G[x][i] ^ 1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0) break;
            }
        }
        if(!flow) d[x] = -1;
        return flow;
    }
    
    int dinic(int s, int t)
    {
        int flow = 0;
        while (BFS())
        {
            memset(cur, 0, sizeof(cur));
            flow += DFS(s, INF);
        }
        return flow;
    }
    
    void D(int x,int y)
    {
        for(int i=0;i<GG[x].size();i++)
        {
            if(GG[x][i]==y) continue;
            if(q[GG[x][i]]) { FF=1; return; }
            q[GG[x][i]]=1;
            D(GG[x][i],x); if(FF ) return ;
            q[GG[x][i]]=0;
        }
    }
    
    int main()
    {
        while(~scanf("%d%d%d",&n,&m,&k))
        {
            init();
            s=0, t=n+m+1;
            for(int i=1;i<=n;i++)
            {
                int x; scanf("%d",&x);
                AddEdge(s,i,x);
            }
            for(int i=1;i<=m;i++)
            {
                int x; scanf("%d",&x);
                AddEdge(n+i,t,x);
            }
    
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    AddEdge(i,n+j,k);
    
            dinic(s,t);
    
            bool fail=0;
            for(int i=0;i<edges.size();i=i+2)
            {
                if(edges[i].from==s && edges[i].flow<edges[i].cap) fail=1;
                if(edges[i].to==t && edges[i].flow<edges[i].cap) fail=1;
            }
    
            if(fail) printf("Impossible
    ");
            else
            {
                FF=0; memset(vis,0,sizeof vis);
    
                for(int i=0;i<edges.size();i=i+1)
                {
                    if(edges[i].flow<edges[i].cap)
                    {
                        if(edges[i].from==s||edges[i].from==t) continue;
                        if(edges[i].to==s||edges[i].to==t) continue;
    
                        GG[edges[i].to].push_back(edges[i].from);
                    }
                }
    
                for(int i=1 ;i<=n ;i++)
                {
                    memset(q,0,sizeof q);
                    q[i]=1; D(i,-1);
                    if(FF) break;
                }
    
                if(FF==1)
                {
                    printf("Not Unique
    ");
                    continue;
                }
    
                printf("Unique
    ");
                int now=1;
                for(int i=0;i<edges.size();i=i+2)
                {
                    if(edges[i].from==s) continue;
                    if(edges[i].to==t) continue;
                    printf("%d",edges[i].flow);
                    if(now%m==0) printf("
    ");
                    else printf(" ");
                    now++;
                }
            }
        }
    
        return 0;
    }
  • 相关阅读:
    程序是访问数据库的组件
    Mac搭建Vue
    Sharding-JDBC基本使用,整合Springboot实现分库分表,读写分离
    随意写写
    maven打包工具assembly打包本地jar的解决办法
    Go语言笔记 (2) 变量命名与多重赋值
    Go语言笔记(1)变量的定义与赋值
    c期末笔记(4)
    c期末笔记(3)
    c期末笔记(2)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6516705.html
Copyright © 2011-2022 走看看