2013编程之美挑战赛—管道系统
分类: 2013编程之美挑战赛
2013-07-20 20:59
121人阅读
评论(0)
收藏
举报
编程之美挑战赛 Description
你正在参与一项输油管道的项目,此项目的目标是架设一组输油管道系统,使得从源头到目的地输送的石油流量最大。如果直接从源头架设管道到目的地,一旦管道有损坏,将无法输送石油。为了增强管道系统抵抗破坏的能力,你决定设置 N – 2 个中间节点,从而把管道分散开来。
源头和目的地可以视为特殊的节点,他们的编号分别为 1 和 N,而其他的中间节点的标号为 2 到 N – 1。每条管道有特定的流量限制 c,石油可以以不超过 c 的速率在管道内流动。两个节点之间至多由一条管道连接,也就是说这两个节点之间单位时间内流动的石油不超过 c。
现在你们已经选定了 N 个节点,并且制定好了建设计划。你想知道,每当一条管道建造完成,从节点 1 到节点 N 最大流量能够增加多少。
Input 输入包括多组数据。第一行是整数 T,表示有多少组测试数据。每组测试数据的第一行包括两个整数 N 和 M,表示节点的数量和将要建造的管道数量。接下来 M 行按建造顺序描述每条管道,每行包括三个整数 i, j, c,表示要在节点 i 和 j 之间建造一条容量为 c 的管道。
1 ≤ T ≤ 100
0 ≤ M ≤ N(N – 1)/2
1 ≤ v ≠ u ≤ N
1 ≤ c ≤ 100
小数据:2 ≤ N ≤ 20
大数据:2 ≤ N ≤ 200 Output 对于每组测试数据,先输出一行“Case #c:”,其中 c 为测试数据编号(从 1 开始)。紧接着按建造顺序输出使得总流量增加的管道编号和相应的增加量,以一个空格隔开。
Sample Input
3 2 1 1 2 3 4 5 1 2 9 2 3 7 3 4 6 2 4 4 1 3 1 5 7 1 2 1 1 3 2 1 4 3 2 5 4 3 2 3 4 3 3 3 5 2
Sample Output
Case #1: 1 3 Case #2: 3 6 4 3 5 1 Case #3: 4 1 5 2 6 1 7 2
[cpp]
view plain
copy
print
?
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <queue>
- #include <fstream>
- using namespace std;
- const int maxn=202;
- int n,m,source,sink;
- int c[maxn][maxn],vis[maxn],pre[maxn];
- int ek()
- {
- memset(vis,0,sizeof(vis));
- int low=(1<<30);
- queue<int> q;
- q.push(source);
- vis[source]=1;
- pre[source]=-1;
- while( !q.empty())
- {
- int u=q.front();
- q.pop();
- for(int i=1;i<=n;i++)
- {
- if(!vis[i]&&c[u][i]>0){
- vis[i]=1;
- pre[i]=u;
- low=(low<c[u][i])?low:c[u][i];
- q.push(i);
- //cout<<“low: “<<low<<endl;
- }
- }
- if(vis[sink])return low;
- }
- return 0;
- }
- int maxflow()
- {
- int flow=0,low;
- while(low=ek())
- {
- int u=sink;
- while(pre[u]!=-1)
- {
- c[pre[u]][u]-=low;
- c[u][pre[u]]+=low;
- u = pre[u];
- }
- flow+=low;
- }
- return flow;
- }
- int main()
- {
- int t,cas=1;
- //ifstream fin;
- //fin.open(“aaa.txt”);
- //cin>>t;
- //fin>>t;
- scanf (“%d”,&t);
- while(t–)
- {
- //cin>>n>>m;
- //fin>>n>>m;
- scanf ( “%d%d”, &n, &m );
- memset(c,0,sizeof(c));
- int mflow=0;
- cout<<“Case #”<<cas++<<“:”<<endl;
- for(int i=0;i<m;i++)
- {
- int x,y,z;
- //cin>>x>>y>>z;
- //fin>>x>>y>>z;
- scanf ( “%d%d%d”, &x, &y, &z );
- c[x][y]+=z;
- c[y][x]+=z;
- source=1;
- sink=n;
- int curflow;
- if(source==sink)
- curflow=0;
- else curflow=maxflow();
- if(curflow>0){
- cout<<i+1<<” “<<curflow<<endl;
- mflow+=curflow;
- }
- }
- //cout<<“maxflow is :”<<mflow<<endl;最大流
- }
- return 0;
- }
大数据貌似要超时。暂时未想到优化的方法。