4 4 0 4 2 1 2 2 3 4 2 4 3 1 2 1 2 3 1 3 4 10 4 3 1 2 5 2 3 2 3 4 3
0 2 1 3
题目大意:
n个岛通过有向边连在一起,countryOne坐落在1号岛上,countryAny坐落在n号岛上,现在1 要进攻 n ,n为了抵御1的攻击,要毁坏边,没条边毁坏要花费,现在1可以在 2-n 任意两个岛上建立一个摧毁不了的边,使得 countryAny 为了抵御进攻最小的花费最大为多少?
解题思路:
解题代码:首先,最小割可以理解成网络流的流量,第一步 ,countryAny肯定要用最小的花费使得图不连通,这个花费就是最小割。
但是,countryOne这个时候可以再建一条边使得图再次连通,所以得找出最小割的边集,边集就是 从 countryOne相邻的点 到 与countryOne不相邻的点 连接的边,
所以,再枚举这条边,添加到残余网络中,求所有答案中最大的与之前的最小割相加就是答案。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=100,maxm=10000;
struct edge{
int u,v,f,next;
}e[maxm+10];
int src,sink,cnt,head[maxn+10];
int visited[maxn+10],marked;
int dist[maxn+10];
int n,m;
void adde(int u,int v,int f){
e[cnt].u=u,e[cnt].v=v,e[cnt].f=f,e[cnt].next=head[u],head[u]=cnt++;
e[cnt].u=v,e[cnt].v=u,e[cnt].f=0,e[cnt].next=head[v],head[v]=cnt++;
}
void bfs(){
marked++;
for(int i=0;i<=sink;i++) dist[i]=0;
queue <int> q;
visited[src]=marked;
q.push(src);
while(!q.empty()){
int s=q.front();
q.pop();
for(int i=head[s];i!=-1;i=e[i].next){
int d=e[i].v;
if(e[i].f>0 && visited[d]!=marked ){
q.push(d);
dist[d]=dist[s]+1;
visited[d]=marked;
}
}
}
}
int dfs(int u,int delta){
if(u==sink) return delta;
else{
int ret=0;
for(int i=head[u];delta && i!=-1;i=e[i].next){
if(e[i].f>0 && dist[e[i].v]==dist[u]+1){
int d=dfs(e[i].v,min(e[i].f,delta));
e[i].f-=d;
e[i^1].f+=d;
delta-=d;
ret+=d;
}
}
return ret;
}
}
int maxflow(){
int ret=0;
while(true){
bfs();
if(visited[sink]!=marked) return ret;
ret+=dfs(src,INF);
}
return ret;
}
void initial(){
cnt=0;
memset(head,-1,sizeof(head));
marked++;
}
void input(){
scanf("%d%d",&n,&m);
src=1,sink=n;
while(m-- >0){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
adde(u,v,w);
}
}
void solve(){
int ans=maxflow();
bool f[maxn+10];
memset(f,false,sizeof(f));
queue <int> q;
q.push(src);
f[src]=true;
while(!q.empty() ){
int s=q.front();
q.pop();
for(int i=head[s];i!=-1;i=e[i].next){
int d=e[i].v;
if(e[i].f>0 && !f[d]){
q.push(d);
f[d]=true;
}
}
}
vector <edge> v;
for(int i=0;i<cnt;i++) v.push_back(e[i]);
int tmp=0;
for(int i=2;i<=n-1;i++){
for(int j=2;j<=n-1;j++){
if( f[i] && ( ! f[j] ) ){
int headu=head[i],headv=head[j];
adde(i,j,INF);
int flow=maxflow();
if(flow>tmp) tmp=flow;
cnt-=2;
head[i]=headu,head[j]=headv;
for(int t=0;t<cnt;t++) e[t]=v[t];
}
}
}
cout<<ans+tmp<<endl;
}
int main(){
int t;
scanf("%d",&t);
while(t-- >0){
initial();
input();
solve();
}
return 0;
}
HDU 2435 There is a war (网络流-最小割),布布扣,bubuko.com
HDU 2435 There is a war (网络流-最小割)
原文:http://blog.csdn.net/a1061747415/article/details/32338483