Description
你第一天接手光明牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批坏牛奶。很不幸,你发现这件事的时候,坏牛奶已经进入了送货网。这个送货网很大,而且关系复杂。你知道这批牛奶要发给哪个零售商,但是要把这批牛奶送到他手中有许多种途径。送货网由一些仓库和运输卡车组成,每辆卡车都在各自固定的两个仓库之间单向运输牛奶。在追查这些坏牛奶的时候,有必要保证它不被送到零售商手里,所以必须使某些运输卡车停止运输,但是停止每辆卡车都会有一定的经济损失。你的任务是,再保证坏牛奶不送到零售商的前提下,制定出停止卡车运输的方案,使损失最小。
Input
第一行: 两个整数N(2<=N<=32)、 M(0<=M<=1000),N表示仓库的数目,M表示运输卡车的数量。仓库1代 表发货工厂,仓库N 代表坏牛奶要发往的零售商。
第2..M+1行: 每行3个整数 Si, Ei, Ci. Si ,Ei表示这 辆卡车的出发仓库,目的仓库。Ci(0 <= C i <= 2,000,000) 表示让这辆卡车停 止运输的损失
Output
第1行两个整数C、T,C表示最小的损失,T表示要停止的最少卡车数。接下来T行表示你要停止哪几条线路(按输入顺序)。 如果有多种方案使损失最小,输出停止的线路最少的方案。如果还有多种方案使损失最小时线路最少,输出字典序最小的方案。
Sample Input
4 5 1 3 100 3 2 50 2 4 60 1 2 40 2 3 80
Sample Output
60 1 3
Solution
给定一个有向图,求割边数最小的最小割集,并按照字典序输出。 根据数据加边,并且将边按照容量的大小排序。按照边的大小顺序并通过枚举的方式得出最小割集,并且将其进行sort排序后输出。具体方式详见
见代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf=99999999;
struct node
{
int x,y,c,next,other,ds;
}a[2100],d[2100];int len,last[2100];
void ins(int x,int y,int c)
{
len++;int k1=len;
a[len].x=x;a[len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len;
len++;int k2=len;
a[len].x=y;a[len].y=x;a[len].c=0;
a[len].next=last[y];last[y]=len;
a[k1].other=k2;
a[k2].other=k1;
}
int list[2100],head,tail,h[2100];
int st,ed,b[2100],lenb;
bool bfs()
{
memset(h,0,sizeof(h));h[st]=1;
list[1]=st;head=1;tail=2;
while(head<tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]==0&&a[k].c>0)
{
h[y]=h[x]+1;
list[tail]=y;
tail++;
}
}
head++;
}
if(h[ed]==0)return false;
else return true;
}
int findflow(int x,int f)
{
if(x==ed)return f;
int s=0;
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(h[y]==h[x]+1&&a[k].c>0&&s<f)
{
int t=findflow(y,min(a[k].c,f-s));
s+=t;a[k].c-=t;a[a[k].other].c+=t;
}
}
if(s==0)h[x]=0;
return s;
}
int cmp(const void *xx,const void *yy)
{
node n1=*(node *)xx;
node n2=*(node *)yy;
if(n1.c<n2.c)return 1;
else return -1;
}
bool bk[21000];
int main()
{
//freopen("milk6.in","r",stdin);
//freopen("milk6.out","w",stdout);
int n,m;scanf("%d%d",&n,&m);
len=0;memset(last,0,sizeof(last));
for(int i=1;i<=m;i++)
{
int x,y,c;scanf("%d%d%d",&x,&y,&c);
ins(x,y,c);d[i].x=x;d[i].y=y;d[i].c=c;d[i].ds=i;
}
st=1;ed=n;
ll ans=0;
while(bfs()==true)ans+=findflow(st,inf);
printf("%lld ",ans);
qsort(d+1,m,sizeof(node),cmp);
memset(bk,false,sizeof(bk));int kk=len;
for(int i=1;i<=m;i++)
{
if(d[i].c<=ans)
{
memset(last,0,sizeof(last));
len=0;
for(int j=1;j<=m;j++)
{
if(bk[d[j].ds]==false&&i!=j)ins(d[j].x,d[j].y,d[j].c);
}
ll sum=0;
while(bfs()==true)sum+=findflow(st,inf);
if(sum+d[i].c==ans)
{
ans-=d[i].c;
bk[d[i].ds]=true;
b[++lenb]=d[i].ds;
}
}
}
printf("%d\n",lenb);
if(lenb!=0)
{
sort(b+1,b+lenb+1);
for(int i=1;i<=lenb;i++)printf("%d\n",b[i]);
}
return 0;
}
省选可能会涉及相关问题