题目链接:
题目描述:
n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑?
解题思路:
因为需要输出流水线要经过的工厂路径,如果要用电脑状态当做节点的话,就GG了。所以建图的时候要把工厂当做节点。对于节点i,能生产si电脑的节点可以进入节点i,能转化ei电脑的节点可以由i节点进入。要注意对于每一个节点要进行拆点,防止流量发生错误。
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 55; 9 const int INF = 0x3f3f3f3f; 10 struct node 11 { 12 int x, s[20], e[20]; 13 } mach[maxn]; 14 struct node1 15 { 16 int s, e, x; 17 } path[maxn*maxn]; 18 int maps[maxn*2][maxn*2], Maps[maxn*2][maxn*2]; 19 int Layer[maxn*2], p, n, num; 20 21 void buildmaps (int s, int e) 22 { 23 for (int i=s; i<=e; i++) 24 { 25 int j, k; 26 for (int j=s; j<=e; j++) 27 { 28 if (i == j) 29 continue; 30 for (k=0; k<p; k++) 31 { 32 if (mach[i].e[k]==2 || mach[j].s[k]==2) 33 continue; 34 if (mach[i].e[k] != mach[j].s[k]) 35 break; 36 } 37 if (k == p) 38 { 39 if (i > 1) 40 Maps[i+n][j] = mach[i].x; 41 else 42 Maps[i][j] = mach[i].x; 43 } 44 } 45 } 46 47 for (int i=0; i<=num; i++) 48 for (int j=0; j<=num; j++) 49 maps[i][j] = Maps[i][j]; 50 } 51 52 bool CountLayer (int s, int e) 53 { 54 queue <int> Q; 55 memset (Layer, 0, sizeof(Layer)); 56 Layer[s] = 1; 57 Q.push (s); 58 59 while (!Q.empty ()) 60 { 61 62 int u = Q.front(); 63 Q.pop(); 64 65 for (int i=0; i<=num; i++) 66 if (!Layer[i] && maps[u][i]) 67 { 68 Layer[i] = Layer[u] + 1; 69 Q.push (i); 70 if (i == e) 71 return true; 72 } 73 } 74 return false; 75 } 76 77 int Dfs (int u, int e, int maxflow) 78 { 79 if (u == e) 80 return maxflow; 81 82 int uflow = 0; 83 for (int i=0; i<=num; i++) 84 { 85 if (maps[u][i] && Layer[i]==Layer[u]+1) 86 { 87 int flow = min(maps[u][i], maxflow - uflow); 88 flow = Dfs (i, e, flow); 89 90 uflow += flow; 91 maps[u][i] -= flow; 92 maps[i][u] += flow; 93 if (uflow == maxflow) 94 break; 95 } 96 } 97 98 if (uflow == 0) 99 Layer[u] = 0; 100 101 return uflow; 102 } 103 104 int Dinic (int s, int e) 105 { 106 int maxflow = 0; 107 108 while (CountLayer(s, e)) 109 maxflow += Dfs(s, e, INF); 110 111 return maxflow; 112 } 113 114 int main () 115 { 116 while (scanf ("%d %d", &p, &n) != EOF) 117 { 118 memset (mach, 0, sizeof(mach)); 119 memset (Maps, 0, sizeof(Maps)); 120 mach[0].x = INF; 121 for (int i=0; i<p; i++) 122 { 123 mach[0].s[i] = INF; 124 mach[1].e[i] = INF; 125 mach[1].s[i] = 1; 126 } 127 128 for (int i=2; i<n+2; i++) 129 { 130 scanf ("%d", &mach[i].x); 131 for (int j=0; j<p; j++) 132 scanf ("%d", &mach[i].s[j]); 133 for (int j=0; j<p; j++) 134 scanf ("%d", &mach[i].e[j]); 135 Maps[i][i+n] = mach[i].x;//拆点 136 } 137 138 int ans, res; 139 res = 0; 140 num = n + n + 1; 141 142 buildmaps (0, n+1); 143 ans = Dinic (0, 1); 144 145 for (int i=2; i<num; i++) 146 { 147 for (int j=2; j<num; j++) 148 { 149 150 if (i == j+n || j==i+n) 151 continue; 152 153 if (Maps[i][j] - maps[i][j] > 0) 154 { 155 path[res].x = Maps[i][j] - maps[i][j]; 156 path[res].s = (i - 2) % n + 1; 157 path[res++].e = (j - 2) % n + 1; 158 } 159 160 } 161 } 162 163 printf ("%d %d\n", ans, res); 164 for (int i=0; i<res; i++) 165 printf ("%d %d %d\n", path[i].s, path[i].e, path[i].x); 166 167 } 168 return 0; 169 }
时间: 2024-10-07 05:50:15