您的位置:首页 > 其它

usaco Pollutant Control

2017-02-08 17:22 375 查看
/*
ID:jinbo wu
TASK:milk6
LANG:C++
*/
#include<bits/stdc++.h>
#define INF 0x7fffffff
using namespace std;
int N,M;
int level[205];
int Si,Ei,Ci;
struct Dinic
{
int c;
int f;
}edge[205][205];
struct node
{
int u,v,c;
int num;
}temp[1001];
bool cmp(node a,node b)
{
return a.c>b.c;
}
bool dinic_bfs()//构造层次网络
{
queue<int> Q;
memset(level,0,sizeof(level));//初始化顶点的层次 为0
Q.push(1);
level[1]=1;
int u,v;
while(!Q.empty())
{
u=Q.front();
Q.pop();
for(v=1;v<=M;v++)
{
if(!level[v]&&edge[u][v].c>edge[u][v].f)//即顶点未被访问过,顶点u,v,存在边
{
level[v]=level[u]+1;//给顶点标记层次
Q.push(v);
}
}
}
return level[M]!=0;//若返回false表明 汇点不在层次网络中
}
int dinic_dfs(int u,int cp)//进行增广
{
int tmp=cp;
int v,t;
if(u==M)
return cp;
for(v=1;v<=M&&tmp;v++)
{
if(level[u]+1==level[v])
{
if(edge[u][v].c>edge[u][v].f)
{
t=dinic_dfs(v,min(tmp,edge[u][v].c-edge[u][v].f));
edge[u][v].f+=t;
edge[v][u].f-=t;
tmp-=t;
}
}
}
return cp-tmp;
}
int dinic()//求出最大流
{
int sum,tf;
sum=tf=0;
while(dinic_bfs())
{
while(tf=dinic_dfs(1,INF))
{
sum+=tf;
}
}
return sum;
}
int main()
{
freopen("milk6.in","r",stdin);
freopen("milk6.out","w",stdout);
cin>>M>>N;
int t=1;
memset(edge,0,sizeof(edge));
int n=N;
while(n--)
{
scanf("%d%d%d",&Si,&Ei,&Ci);
edge[Si][Ei].c+=Ci;//防止重边
temp[t].num=t;
temp[t].u=Si,temp[t].v=Ei;
temp[t++].c=Ci;
}
int S=dinic();
int a[10005];
int cnt=0;
int sum=0;
sort(temp+1,temp+t,cmp);
for(int i=1;i<=N;i++)
{
for(int k=1;k<=M;k++)
for(int j=1;j<=M;j++)
edge[k][j].f=0;
int u1=temp[i].u;
int v1=temp[i].v;
edge[u1][v1].c=edge[u1][v1].c-temp[i].c;
int s=dinic();
if(s+temp[i].c==S)
{

a[cnt++]=temp[i].num;
sum+=temp[i].c;
if(sum==S)
break;
}
edge[u1][v1].c=edge[u1][v1].c+temp[i].c;
}
sort(a,a+cnt);
cout<<S<<" "<<cnt<<endl;
for(int i=0;i<cnt;i++)
cout<<a[i]<<endl;

return 0;  }
最大流等于最小割,所以我直接把最大流模板套上去了,然后发现输出很烦人。要输出切边最小还要字典序,还好这题数据很小,而且我感觉把边按照全职排序在判断便再找到边数最少的割边不是很正确反正这题就这么水过了

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: