地址:点击打开链接
The regime of a small but wealthy dictatorship has been abruptly overthrown by an unexpected rebellion.Because of the enormous disturbances this is causing in world economy, an imperialist militarysuper power has decided to invade the country and reinstall the old regime.For this operation to be successful, communication between the capital and the largest city mustbe completely cut. This is a difficult task, since all cities in the country are connected by a computernetwork using the Internet Protocol, which allows messages to take any path through the network.Because of this, the network must be completely split in two parts, with the capital in one part andthe largest city in the other, and with no connections between the parts.There are large differences in the costs of sabotaging different connections, since some are muchmore easy to get to than others.Write a program that, given a network specification and the costs of sabotaging each connection,determines which connections to cut in order to separate the capital and the largest city to the lowestpossible cost.InputInput file contains several sets of input. The description of each set is given below.The first line of each set has two integers, separated by a space: First one the number of cities, n inthe network, which is at most 50. The second one is the total number of connections, m, at most 500.The following m lines specify the connections. Each line has three parts separated by spaces: Thefirst two are the cities tied together by that connection (numbers in the range 1 − n). Then follows thecost of cutting the connection (an integer in the range 1 to 40000000). Each pair of cites can appearat most once in this list.Input is terminated by a case where values of n and m are zero. This case should not be processed.For every input set the capital is city number 1, and the largest city is number 2.OutputFor each set of input you should produce several lines of output. The description of output for each setof input is given below:The output for each set should be the pairs of cities (i.e. numbers) between which the connectionshould be cut (in any order), each pair on one line with the numbers separated by a space. If there ismore than one solution, any one of them will do.Print a blank line after the output for each set of input.
Sample Input
5 81 4 301 3 705 3 204 3 54 5 155 2 103 2 252 4 505 81 4 301 3 705 3 204 3 54 5 155 2 103 2 252 4 500 0
Sample Output4 13 43 53 24 13 43 53 2
题意:
要把一个图分成两部分,要把点1和点2分开。隔断每条边都有一个花费,求最小花费的情况下,应该切断那些边。
思路:
模板题,整了一上午愣是没整出来,原来错在初始化上,气啊!!!!初始化要全部初始化,n-》maxn便可。其他的就是模板了
代码:
#include<map>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define maxn 40000
#define PI acos(-1.0)
#define INF 1e9
using namespace std;
typedef long long ll;
struct Edge{
int from,to,cap,flow;
Edge(){}
Edge(int f,int t,int c,int fl):from(f),to(t),cap(c),flow(fl){}
};
struct Dinic{
int n,m,s,t;
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
void init(int n){
this->n=n;
for(int i=0;i<maxn;i++){
G[i].clear();
d[i]=0;
}
edges.clear();
}
void AddEdge(int from,int to,int cap){
edges.push_back((Edge){from,to,cap,0});
edges.push_back((Edge){to,from,0,0}) ;
m=edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BFS(){
memset(vis,0,sizeof(vis));
queue<int>Q;
Q.push(s);
d[s] = 0;
vis[s]=1;
while(!Q.empty()){
int x=Q.front();
Q.pop();
for(int i=0;i<G[x].size();i++){
Edge &e=edges[G[x][i]];
if(!vis[e.to]&&e.cap>e.flow){
vis[e.to]=1;
d[e.to]=d[x]+1;
Q.push(e.to);
}
}
}
return vis[t] ;
}
int DFS(int x,int a) {
if(x==t||a==0) return a;
int flow=0,f;
for(int& i=cur[x];i<G[x].size();i++){
Edge& e =edges[G[x][i]];
if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){
e.flow+=f;
edges[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0) break;
}
}
return flow;
}
int Maxflow(int s,int t){
this->s=s;
this->t=t;
int flow=0;
while(BFS()){
memset(cur,0,sizeof(cur));
flow+=DFS(s,INF);
//flow+=DFS(s,INF);
}
return flow;
}
void Mincut(){
BFS();
for(int i=0; i<edges.size();i++){
Edge& e=edges[i];
if( vis[e.from] && !vis[e.to] &&e.cap>0)
cout<<edges[i].from<<" "<<edges[i].to<<endl;
}
}
}DC;
int main()
{
int n,m;
while(scanf("%d%d", &n, &m) == 2)
{
int u,v,c;
for(int i=1;i<=m;i++){
cin>>u>>v>>c;
DC.AddEdge(u,v,c);
DC.AddEdge(v,u,c);
}
DC.Maxflow(1,2);
DC.Mincut();
DC.init(n);
cout<<endl;
}
return 0;
}