• UVa11248 Frequency Hopping(最大流+最小割)


    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33206

    【思路】

           最大流最小割。

           可以确定的是如果不可行需要修改的是流量已经达到上限的最小割中的边。可以考虑依次修改求最大流。

           优化:1 在原最大流的基础上增广; 2 只增广到流量C为止。

    【代码】

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 #include<vector>
      5 #include<algorithm>
      6 using namespace std;
      7 
      8 const int maxn = 100+10;
      9 const int INF = 1e9*2+10;
     10 
     11 struct Edge{
     12     int u,v,cap,flow;
     13     bool operator<(const Edge& rhs) const{
     14         return u<rhs.u || (u==rhs.u && v<rhs.v) ;
     15     }
     16 };
     17 struct Dinic {
     18     int n,m,s,t;
     19     bool vis[maxn];
     20     int d[maxn],cur[maxn];
     21     vector<int> G[maxn];
     22     vector<Edge> es;
     23     
     24     void init(int n) {
     25         this->n=n;
     26         es.clear();
     27         for(int i=0;i<n;i++) G[i].clear();
     28     }
     29     void clearflow() {
     30         for(int i=0;i<es.size();i++) es[i].flow=0;
     31     }
     32     void AddEdge(int u,int v,int cap) {
     33         es.push_back((Edge){u,v,cap,0});
     34         es.push_back((Edge){v,u,0,0});
     35         m=es.size();
     36         G[u].push_back(m-2);
     37         G[v].push_back(m-1);
     38     }
     39     
     40     bool BFS() {
     41         queue<int> q;
     42         memset(vis,0,sizeof(vis));
     43         q.push(s); vis[s]=1; d[s]=0;
     44         while(!q.empty()) {
     45             int u=q.front(); q.pop();
     46             for(int i=0;i<G[u].size();i++) {
     47                 Edge& e=es[G[u][i]];
     48                 int v=e.v;
     49                 if(!vis[v] && e.cap>e.flow) {
     50                     vis[v]=1;
     51                     d[v]=d[u]+1;
     52                     q.push(v);
     53                 }
     54             }
     55         }
     56         return vis[t];
     57     }
     58     int DFS(int u,int a) {
     59         if(u==t || a==0) return a;
     60         int flow=0,f;
     61         for(int& i=cur[u];i<G[u].size();i++){
     62             Edge& e=es[G[u][i]];
     63             int v=e.v;
     64             if( d[v]==d[u]+1 && (f=DFS(v,min(a,e.cap-e.flow)))>0 ) {
     65                 e.flow+=f;
     66                 es[G[u][i]^1].flow-=f;
     67                 flow+=f,a-=f;
     68                 if(!a) break;
     69             }
     70         }
     71         return flow;
     72     }
     73     int Maxflow(int s,int t,int limit) {
     74         this->s=s , this->t=t;
     75         int flow=0;
     76         while(BFS() && flow<limit) {
     77             memset(cur,0,sizeof(cur));
     78             flow+=DFS(s,INF);
     79         }
     80         return flow;
     81     }
     82     vector<int> Mincut() {
     83         vector<int> ans;
     84         for(int i=0;i<es.size();i++)
     85             if(es[i].cap!=0 && es[i].cap==es[i].flow)
     86                  ans.push_back(i);
     87         return ans;
     88     }
     89     void reduce() {
     90         for(int i=0;i<es.size();i++) es[i].cap-=es[i].flow;
     91     }
     92 }dc;
     93 
     94 int n,m,C;
     95 
     96 int main() {
     97     int kase=0;
     98     while(scanf("%d%d%d",&n,&m,&C)==3 && n) {
     99         dc.init(n);
    100         int u,v,w;
    101         for(int i=0;i<m;i++) {
    102             scanf("%d%d%d",&u,&v,&w);
    103             u--,v--;
    104             dc.AddEdge(u,v,w);
    105         }
    106         int flow=dc.Maxflow(0,n-1,INF);
    107         printf("Case %d: ",++kase);
    108         if(flow>=C) printf("possible
    ");
    109         else {
    110             vector<int> cut;
    111             vector<Edge> ans;
    112             cut=dc.Mincut();
    113             dc.reduce();            //考虑除去最大流之后的剩余网络//即在原流基础上增广 
    114             for(int i=0;i<cut.size();i++) {
    115                 dc.clearflow();
    116                 Edge& e=dc.es[cut[i]];
    117                 int tmp=e.cap;
    118                 e.cap=C;
    119                 if(flow+dc.Maxflow(0,n-1,C-flow)>=C) ans.push_back(e);
    120                 e.cap=tmp;
    121             }
    122             if(!ans.size()) printf("not possible
    ");
    123             else {
    124                 sort(ans.begin(),ans.end());
    125                 printf("possible option:");
    126                 int d=ans.size();
    127                 for(int i=0;i<d-1;i++) printf("(%d,%d),",ans[i].u+1,ans[i].v+1); 
    128                 printf("(%d,%d)
    ",ans[d-1].u+1,ans[d-1].v+1);
    129             }
    130         }
    131     }
    132     return 0;
    133 }

          

  • 相关阅读:
    Java学习10——package和import
    第一次作业_031502532_吴智慧
    Java学习9——面向对象
    Java学习8——类(对象)之间的关系
    Java学习7——一些注意的地方
    Java学习5——标识符和关键字
    Zookeeper集群和HBase集群
    Zookeeper、HBase的伪分布
    hive学习笔记——表的基本的操作
    hive 学习笔记——表的入门操作和命令
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5059573.html
Copyright © 2020-2023  润新知