1. 程式人生 > 實用技巧 >Linux 配置埠對映

Linux 配置埠對映

網路流24題

洛谷題單:網路流24題

第一題:飛行員配對問題

二分圖模板題,匈牙利可以過,並且匈牙利演算法可以記錄匹配的資訊

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 #define N 100010
 6 using namespace std;
 7 int cnt, n, m, head[N], nxt[N], to[N], p[N];
 8 bool vis[N];
 9 inline int read() {
10 int x = 0, y = 1; 11 char c = getchar(); 12 while (c < '0' || c > '9') { 13 if (c == '-') 14 y = -1; 15 c = getchar(); 16 } 17 while (c >= '0' && c <= '9') 18 x = x * 10 + c - '0', c = getchar(); 19 return x * y; 20 } 21 void
add(int x, int y) { 22 nxt[++cnt] = head[x]; 23 head[x] = cnt; 24 to[cnt] = y; 25 } 26 bool match(int u) { 27 for (int i = head[u]; ~i; i = nxt[i]) { 28 int v = to[i]; 29 if (vis[v]) 30 continue; 31 else 32 vis[v] = true; 33 if (p[v] == 0
|| match(p[v])) { 34 p[v] = u; 35 return true; 36 } 37 } 38 return false; 39 } 40 int pipei() { 41 int ans = 0; 42 for (int i = 1; i <= m; i++) { 43 memset(vis, false, sizeof(vis)); 44 if (match(i)) 45 ans++; 46 } 47 return ans; 48 } 49 int main() { 50 cnt = -1; 51 memset(head, -1, sizeof(head)); memset(p,0,sizeof(p)); 52 m = read(); 53 n = read(); 54 int u, v; 55 while (~scanf("%d%d", &u, &v) && u+v != -2) add(u, v); 56 int k = pipei(); 57 printf("%d\n",k); 58 for(int i = m+1; i <= n; i++) 59 if(p[i] != 0) 60 printf("%d %d\n",p[i],i); 61 return 0; 62 }
View Code

第二題:太空飛行計劃問題

最小割的應用,最大權閉合子圖模板題,源點建正權,匯點建負權

最大權閉合子圖的權值和=max{被選擇的點權和}=正點權和min{沒被選擇的正權點之和+被選擇的負權點絕對值和}

=正點權和最小割

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 #include <vector>
  6 #define N 10010
  7 using namespace std;
  8 vector<int> g[N];
  9 int cnt,n,m,s,t,head[N],nxt[N],to[N],d[N],cur[N],w[N],f[N];
 10 const int INF = 0x3f3f3f3f;
 11 void add(int x, int y, int z)
 12 {
 13     nxt[++cnt] = head[x];
 14     head[x] = cnt;
 15     to[cnt] = y;
 16     w[cnt] = z;
 17 }
 18 bool bfs(int s, int t)
 19 {
 20     memset(d,-1,sizeof(d));
 21     d[s] = 0;
 22     queue<int> q;
 23     q.push(s);
 24     while(!q.empty())
 25     {
 26         int p = q.front(); q.pop();
 27         for(int i = head[p]; ~i; i = nxt[i])
 28         {
 29             int v = to[i];
 30             if(d[v] == -1 && w[i])
 31             {
 32                 d[v] = d[p]+1;
 33                 q.push(v);
 34             }
 35         }
 36     }
 37     return d[t] != -1;
 38 }
 39 int dfs(int s, int flow)
 40 {
 41     if(s == t) return flow;
 42     int ans = 0;
 43     for(int i = cur[s]; ~i; i = nxt[i])
 44     {
 45         int v = to[i];
 46         cur[s] = i;
 47         if(d[v] == d[s]+1 && w[i])
 48         {
 49             int dis = dfs(v,min(flow,w[i]));
 50             if(dis)
 51             {
 52                 w[i] -= dis;
 53                 w[i^1] += dis;
 54                 flow -= dis;
 55                 ans += dis;
 56                 if(flow == 0) break;
 57             }
 58         }
 59     }
 60     return ans;
 61 }
 62 int dinic(int s, int t)
 63 {
 64     int ans = 0;
 65     while(bfs(s,t))
 66     {
 67         memcpy(cur,head,sizeof(head));
 68         ans += dfs(s,INF);
 69     }
 70     return ans;
 71 }
 72 int main()
 73 {
 74     int sum = 0;
 75     cnt = -1; memset(head,-1,sizeof(head));
 76     scanf("%d%d",&m,&n);
 77     s = 0; t = n+m+1;
 78     for(int i = 1; i <= m; i++)
 79     {
 80         int x; char c;
 81         scanf("%d",&x);
 82         sum += x;
 83         add(s,i+n,x); add(i+n,s,0);
 84         while(true)
 85         {
 86             scanf("%d%c",&x,&c);
 87             add(i+n,x,INF); add(x,i+n,0);
 88             if(c == '\n' || c == '\r') break;
 89         }
 90     }
 91     for(int i = 1; i <= n; i++)
 92     {
 93         int x;
 94         scanf("%d",&x);
 95         add(i,t,x); add(t,i,0);
 96     }
 97     sum -= dinic(s,t);
 98     for(int i = 1; i <= m; i++)
 99         if(d[i+n] != -1)
100             printf("%d ",i);
101     puts("");
102     for(int i = 1; i <= n; i++)
103         if(d[i] != -1)
104             printf("%d ",i);
105     puts("");
106     printf("%d\n",sum);
107     return 0;
108 }
View Code