程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> USACO5.4-TeleCowmunication,

USACO5.4-TeleCowmunication,

編輯:C++入門知識

USACO5.4-TeleCowmunication,



題目大意:給出一個無向圖,要求刪除盡量少的點,使給定的2點間不再連通,並輸出字典序最小的方案
題型:圖論-網絡流
此題難點在於建圖,後面就是套網絡流的模板.
將點看成邊,例如第i個點可以看成一條有向邊<i*2-1,i*2>,容量為1.
如果j點和i點鄰接,那麼新建2條容量為無窮大的有向邊<i*2,j*2-1>,<j*2,i*2-1>.
然後應用最大流最小割定理,求最大流即為第一問答案.
接著枚舉刪除每一個點i(即刪除有向邊),看最大流是否減少1,如果是則該點在最小割中,然後真的把這一點刪點.
枚舉完每個點之後別忘了將殘量網絡還原.
至於為什麼要這樣建圖, 一時間說不清楚......

Executing...
Test 1: TEST OK [0.008 secs, 3852 KB]
Test 2: TEST OK [0.014 secs, 3852 KB]
Test 3: TEST OK [0.005 secs, 3852 KB]
Test 4: TEST OK [0.022 secs, 3852 KB]
Test 5: TEST OK [0.011 secs, 3852 KB]
Test 6: TEST OK [0.019 secs, 3852 KB]
Test 7: TEST OK [0.019 secs, 3852 KB]
Test 8: TEST OK [0.014 secs, 3852 KB]
Test 9: TEST OK [0.032 secs, 3852 KB]
Test 10: TEST OK [0.046 secs, 3852 KB]
Test 11: TEST OK [0.068 secs, 3852 KB]

All tests OK.
Your program ('telecow') produced all correct answers! This is your
submission #3 for this problem. Congratulations!

 

  1 #include <iostream>
  2 #include <cstring>
  3 #include <queue>
  4 #include <stdio.h>
  5 #define msize 210
  6 #define INF 1000000000
  7 using namespace std;
  8 
  9 int origin[msize][msize]={0};
 10 int r[msize][msize]={0}; //殘留網絡,初始為原圖
 11 bool visited[msize];
 12 int pre[msize];
 13 int m,nVertex; //n條邊,m個頂點
 14 
 15 bool bfs(int s,int t) //尋找一條從s到t的增廣路,若找到,返回true
 16 {
 17     int p;
 18     queue<int> Q;
 19     memset(pre,-1,sizeof(pre));
 20     memset(visited,false,sizeof(visited));
 21 
 22     pre[s]=s;
 23     visited[s]=true;
 24     Q.push(s);
 25 
 26     while (!Q.empty())
 27     {
 28         p=Q.front(),Q.pop();
 29         for (int i=1; i<=nVertex; i++)
 30         {
 31             if (r[p][i]>0&&!visited[i])
 32             {
 33                 pre[i]=p;
 34                 visited[i]=true;
 35                 if (i==t) return true;
 36                 Q.push(i);
 37             }
 38         }
 39     }
 40 
 41     return false;
 42 }
 43 
 44 int maxFlow(int s,int t)
 45 {
 46     int flow=0,d;
 47 
 48     while (bfs(s,t))
 49     {
 50         d=INF;
 51         for (int i=t; i!=s; i=pre[i]) d=min(d,r[pre[i]][i]);
 52         for (int i=t; i!=s; i=pre[i]) r[pre[i]][i] -= d, r[i][pre[i]] += d;
 53         flow += d;
 54     }
 55     return flow;
 56 }
 57 
 58 int main()
 59 {
 60     freopen("telecow.in","r",stdin);
 61     freopen("telecow.out","w",stdout);
 62     int s,e,c;
 63 
 64     cin>>nVertex>>m>>s>>e;
 65     nVertex*=2;
 66     for(int i=0;i<m;i++)
 67     {
 68         int a,b;
 69         scanf("%d%d",&a,&b);
 70         r[a*2-1][a*2]=1;
 71         r[b*2-1][b*2]=1;
 72         r[a*2][b*2-1]=INF;
 73         r[b*2][a*2-1]=INF;
 74     }
 75     memcpy(origin,r,sizeof r);
 76     int maxflow=maxFlow(s*2,e*2-1);
 77     int sum=maxflow;
 78     memcpy(r,origin,sizeof r);
 79     printf("%d\n",maxflow);
 80 
 81     bool first=true;
 82     int cnt=0;
 83     for(int i=1;i<=nVertex/2;i++) // 模擬刪掉第i個點
 84     {
 85         if(i==s || i==e)
 86             continue;
 87         if(cnt==sum)
 88         {
 89             break;
 90         }
 91         memcpy(origin,r,sizeof r);
 92         r[i*2-1][i*2]=0;
 93 
 94         if(maxFlow(s*2,e*2-1)+1==maxflow)
 95         {
 96             maxflow--;
 97             cnt++;
 98             if(first)
 99             {
100                 first=false;
101             }
102             else
103             {
104                 printf(" ");
105             }
106             printf("%d",i);
107             memcpy(r,origin,sizeof r);
108             r[i*2-1][i*2]=0;
109         }
110         else
111         {
112             memcpy(r,origin,sizeof r);
113         }
114     }
115     cout<<endl;
116     return 0;
117 }

 




  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved