zoukankan      html  css  js  c++  java
  • uvalive 3231 Fair Share 公平分配问题 二分+最大流 右边最多流量的结点流量尽量少。

    /**
    题目: uvalive 3231 Fair Share 公平分配问题
    链接:https://vjudge.net/problem/UVALive-3231
    题意:有m个任务,n个处理器,每个任务有两个候选处理器,只要其中一个运行,该任务就能执行。
    不同任务的两个候选处理器,至少有一个不同。 求任务数最多的那个处理器所分配的任务数尽量少。
    
    思路:二分+最大流
    
    左边是任务,s->u,cap = 1。
    如果任务u和u的候选处理器v,u->v, cap = 1.
    右边是处理器,二分mi。所有处理器v,v->t, cap = mi;
    
    求s-t最大流flow,如果flow等于任务数,那么可行解。找一个最小的mi即可。
    */
    
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<map>
    #include<cstdio>
    #include<sstream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long LL;
    const int INF = 0x3f3f3f3f;
    typedef long long LL;
    const int N = 11010;///n+m=1000+10000=11000;
    struct Edge{
        int from, to, cap, flow;
        Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
    };
    struct Dinic{
      int n, m, s, t;
      vector<Edge> edges;
      vector<int> G[N];
      bool vis[N];
      int d[N];
      int cur[N];
    
      void init(int n)
      {
        this->n = n;
        for(int i = 0; i <= n; i++) G[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));
        m = edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-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){
                e.flow += f;
                edges[G[x][i]^1].flow -= f;
                flow += f;
                a -= f;
                if(a==0) break;
            }
        }
        return flow;
      }
    
      int Maxflow(int s,int t){
        this->s = s, this->t = t;
        int flow = 0;
        while(BFS()){
            memset(cur, 0, sizeof cur);
            flow += DFS(s,INF);
        }
        return flow;
      }
    };
    int main()
    {
        int T, n, m;
        cin>>T;
        while(T--)
        {
            scanf("%d%d",&n,&m);
            int s = 0, t = n+m+1;
            Dinic dinic, save;
            dinic.init(t);
            int u , v;
            for(int i = 1; i <= m; i++){
                scanf("%d%d",&u,&v);
                dinic.AddEdge(s,i,1);
                dinic.AddEdge(i,u+m,1);
                dinic.AddEdge(i,v+m,1);
            }
            save = dinic;
            int lo = 0, hi = INF, mi, ans;
            while(lo<=hi){
                mi = (lo+hi)/2;
                dinic = save;
                for(int i = 1; i <= n; i++){
                    dinic.AddEdge(i+m,t,mi);
                }
                int flow = dinic.Maxflow(s,t);
                if(flow==m){
                    ans = mi;
                    hi = mi-1;
                }else
                {
                    lo = mi+1;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    iOS开发技巧系列---使用链式编程和Block来实现UIAlertView
    那些著名或非著名的iOS面试题-前编
    App安全之网络传输安全
    高效使用jquery之一:请使用'On'函数
    手把手教你在.NET中创建Web服务
    CSS3弹性盒模型布局模块介绍
    推荐一款超级漂亮的HTML5 CSS3的图片轮播器
    深入了解jquery中的键盘事件
    Javascript实现返回上一页面并刷新
    jQuery中下拉框select的操作方法详解
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7220431.html
Copyright © 2011-2022 走看看