USACO SECTION 4.4 Pollutant Control

Pollutant Control
Hal Burch

It's your first day in Quality Control at Merry Milk Makers, and already there's been a catastrophe: a shipment of bad milk has been sent out. Unfortunately, you didn't discover this until the milk was already into your delivery system on its way to stores. You know which grocer that milk was destined for, but there may be multiple ways for the milk to get to that store.

The delivery system is made up of a several warehouses, with trucks running from warehouse to warehouse moving milk. While the milk will be found quickly, it is important that it does not make it to the grocer, so you must shut down enough trucks to ensure that it is impossible for the milk to get to the grocer in question. Every route costs a certain amount to shut down. Find the minimum amount that must be spent to ensure the milk does not reach its destination, along with a set of trucks to shut down that achieves this goal at that cost.

PROGRAM NAME: milk6

INPUT FORMAT

Line 1:Two space separated integers, N and M. N (2 <= N <= 32) is the number of warehouses that Merry Milk Makers has, and M (0 <= M <= 1000) is the number of trucks routes run. Warehouse 1 is actually the productional facility, while warehouse N is the grocer to which which the bad milk was destined.
Line 2..M+1:Truck routes: three space-separated integers, Si, Ei, and Ci. Si and Ei (1 <= Si,Ei <= N) correspond to the pickup warehouse and dropoff warehouse for the truck route. Ci (0 <= Ci <= 2,000,000) is the cost of shutting down the truck route.

SAMPLE INPUT (file milk6.in)

4 5
1 3 100
3 2 50
2 4 60
1 2 40
2 3 80

OUTPUT FORMAT

The first line of the output should be two integers, C and T. C is the minimum amount which must be spent in order to ensure the our milk never reaches its destination. T is the minimum number of truck routes that you plan to shut down in order to achive this goal. The next T lines sould contain a sorted list of the indexes of the truck routes that you suggest shutting down. If there are multiple sets of truck routes that achieve the goal at minimum cost, choose one that shuts down the minimum number of routes. If there are still multiple sets, choose the one whose initial routes have the smallest index.

SAMPLE OUTPUT (file milk6.out)

60 1
3
/*
ID: conicoc1
LANG: C
TASK: milk6
*/

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define INIFINITY 10000000
#define Min(a,b) a<b?a:b

int Temp[1001][2];
int Map[33][33];
int Dist[33];
int Flag[33];
int Vertex,Edges;
int Queue[33];
int Front=0,Rear=0;
int Ans1,Ans2[1001];
int Union[33];
int GAP[33];

int BuildDist()
{
	memset(GAP,0,sizeof(GAP));
	int V,i;
	Queue[Rear++]=Vertex;
	Dist[Vertex]=0;
	Flag[Vertex]=1;
//	GAP[0]=1;
	while(Front!=Rear){
		V=Queue[Front++];
		for(i=1;i<=Vertex;i++){
			if(Map[i][V]&&!Flag[i]){
				Dist[i]=Dist[V]+1;
//				GAP[Dist[i]]++;
				Flag[i]=1;
				Queue[Rear++]=i;
			}
		}
	}
}

void SAP()
{
	int i,Flow,V,Path[33];
	V=1;
	Ans1=0;
	while(Dist[1]<Vertex){
		if(V==Vertex){
			Flow=INIFINITY;
			while(V!=1){
				Flow=Min(Flow,Map[Path[V]][V]);
				V=Path[V];
			}
			V=Vertex;
			while(V!=1){
				Map[Path[V]][V]-=Flow;
				Map[V][Path[V]]+=Flow;
				V=Path[V];
			}
			Ans1+=Flow;
		}
		else{
			for(i=1;i<=Vertex;i++){
				if(Map[V][i]&&Dist[V]==Dist[i]+1){
					Path[i]=V;
					V=i;
					break;
				}
			}
			if(i==Vertex+1){
//				GAP[Dist[V]]--;
//				if(GAP[Dist[V]]==0)
//					break;
				Dist[V]=Vertex;
				for(i=1;i<=Vertex;i++){
					if(Map[V][i]&&Dist[i]!=-1)
						Dist[V]=Min(Dist[V],Dist[i]+1);
				}
//				GAP[Dist[V]]++;
				if(V!=1)
					V=Path[V];
			}
		}
	}
}

void FloodFill(int V)
{
	int W;
	Union[V]=Flag[V]=1;
	for(W=1;W<=Vertex;W++)
		if(Map[V][W]&&!Flag[W]){
			FloodFill(W);
		}	
}

int main()
{
	FILE *fin,*fout;
	int i,j,V,W,Dis;
	int TmpAns[1000];
	fin=fopen("milk6.in","r");
	fout=fopen("milk6.out","w");
	memset(Map,0,sizeof(Map));
	fscanf(fin,"%d %d",&Vertex,&Edges);
	for(i=1;i<=Edges;i++){
		fscanf(fin,"%d %d %d",&V,&W,&Dis);
		Map[V][W]+=Dis;
		Temp[i][0]=V;
		Temp[i][1]=W;
	}
	memset(Dist,-1,sizeof(Dist));
	BuildDist();
	SAP();
	Ans2[0]=(Ans1?INIFINITY:0);
	for(i=1;i<=Vertex;i++){
		memset(Flag,0,sizeof(Flag));
		memset(Union,0,sizeof(Union));
		memset(TmpAns,0,sizeof(TmpAns));
		FloodFill(i);
		if(Union[1]==Union[Vertex])
			continue;
		for(j=1;j<=Edges;j++)
			if(Union[Temp[j][0]]&&Union[Temp[j][0]]!=Union[Temp[j][1]])
				TmpAns[++TmpAns[0]]=j;
		if(TmpAns[0]<Ans2[0]||(TmpAns[0]==Ans2[0]&&TmpAns[1]<Ans2[1])){
			Ans2[0]=TmpAns[0];
			for(j=1;j<=TmpAns[0];j++)
				Ans2[j]=TmpAns[j];
		}
	}
	fprintf(fout,"%d %d\n",Ans1,Ans2[0]);
	for(i=1;i<=Ans2[0];i++){
		fprintf(fout,"%d\n",Ans2[i]);
	}
	return 0;
}


最小割+残留网络的FloodFill胡搞一气。。。貌似还用了并查集?还不是为了找到边数最少的那组!

最大流用的SAP算法+GAP优化,话说一开始SAP求当前最大流的时候没有给最大流赋值为无穷。。结果各种超时悲剧

虽然是模板还是得自己多打打才能减少错误。。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值