zoukankan      html  css  js  c++  java
  • [USACO5.4]Telecowmunication

    OJ题号:
    洛谷1345

    思路:

    求无向图最大流最小点割集。
    首先将每个点拆成两个,对于自己,连一条容量为$1$的边,对于原来的边,对$(xprime,y)$$(yprime,x)$分别连一条容量为$infty$的边,这样我们就将最小点割转化成了最小边割,根据最大流最小割定理,直接跑最大流即可。
    如何求出字典序最小的集?
    一个点在最小点割集中当且仅当删去这个点时,最大流变小。因此我们可以从小到大枚举删除每个点,求得删除该点之后的最大流,若最大流变小则将其加入答案集合,恢复残量网络并删除这个点,直到最大流变为$0$。

    注:USACO Training原题要求按字典序输出点集,而这题在洛谷只要求输出集合大小,校内OJ又卡评测,故在程序代码中没有体现。

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<vector>
     5 #include<cstring>
     6 inline int getint() {
     7     char ch;
     8     while(!isdigit(ch=getchar()));
     9     int x=ch^'0';
    10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    11     return x;
    12 }
    13 const int inf=0x7fffffff;
    14 int s,t;
    15 const int E=2600,V=201;
    16 struct Edge {
    17     int from,to,remain;
    18 };
    19 Edge e[E];
    20 std::vector<int> g[V];
    21 int sz=0;
    22 inline void add_edge(const int u,const int v,const int w) {
    23     e[sz]=(Edge){u,v,w};
    24     g[u].push_back(sz);
    25     sz++;
    26 }
    27 int a[V],p[V];
    28 inline int Augment() {
    29     memset(a,0,sizeof a);
    30     a[s]=inf;
    31     std::queue<int> q;
    32     q.push(s);
    33     while(!q.empty()) {
    34         int x=q.front();
    35         q.pop();
    36         for(unsigned i=0;i<g[x].size();i++) {
    37             Edge &y=e[g[x][i]];
    38             if(!a[y.to]&&y.remain) {
    39                 p[y.to]=g[x][i];
    40                 a[y.to]=std::min(y.remain,a[x]);
    41                 q.push(y.to);
    42             }
    43         }
    44         if(a[t]) break;
    45     }
    46     return a[t];
    47 }
    48 inline int EdmondsKarp() {
    49     int maxflow=0;
    50     while(int flow=Augment()) {
    51         for(int i=t;i!=s;i=e[p[i]].from) {
    52             e[p[i]].remain-=flow;
    53             e[p[i]^1].remain+=flow;
    54         }
    55         maxflow+=flow;
    56     }
    57     return maxflow;
    58 }
    59 int main() {
    60     int n=getint(),m=getint();
    61     s=getint()+n,t=getint();
    62     for(int i=0;i<m;i++) {
    63         int u=getint(),v=getint();
    64         add_edge(u+n,v,inf);
    65         add_edge(v,u+n,0);
    66         add_edge(v+n,u,inf);
    67         add_edge(u,v+n,0);
    68     }
    69     for(int i=1;i<=n;i++) {
    70         add_edge(i,i+n,1);
    71         add_edge(i+n,i,0);
    72     }
    73     printf("%d
    ",EdmondsKarp());
    74     return 0;
    75 }
  • 相关阅读:
    自动化测试-18.selenium之bugFree代码注释
    自动化测试-16.selenium数据的分离之Excel的使用
    自动化测试-15.selenium单选框与复选框状态判断
    自动化测试-14.selenium加载FireFox配置
    自动化测试-13.selenium执行JS处理滚动条
    Lucas-Kanade算法总结
    迟来的2013年总结及算法工程师/研究员找工作总结
    Android从文件读取图像显示的效率问题
    Viola Jones Face Detector
    谈谈Android中的SurfaceTexture
  • 原文地址:https://www.cnblogs.com/skylee03/p/7389569.html
Copyright © 2011-2022 走看看