C++——【USACO 4.4.2】——Pollutant Control

44 篇文章 0 订阅

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

污染物控制
这是你在快乐牛奶制造商的质量控制的第一天,而且已经发生了一场灾难:一批劣质牛奶已经被送出。不幸的是,直到牛奶已经进入你的配送系统,你才发现这一点。你知道牛奶是用来做什么食品的,但是牛奶可以有多种方式到达那家商店。
配送系统由几个仓库组成,卡车到仓库搬运牛奶。虽然牛奶很快就会被发现,但重要的是它不能被送到杂货店,所以你必须关闭足够多的卡车,以确保牛奶不可能到达食品杂货店。每条路线都要花费一定的代价才能关闭。找出必须花费的最低量,以确保牛奶没有到达目的地,同时还有一组卡车关闭,以达到这个目标。
项目名称:milk6
输入格式
第1行:两个空间分隔的整数N和M N(2 <= N <= 32)是快乐牛奶制造商的仓库数量,M(0 <= M <= 1000)是卡车路线运行的数量。仓库1实际上是生产基地,而仓库N则是坏牛奶的目的地。
2号线. .M+ 1:卡车路线:三个空间分隔的整数,Si,Ei和Ci。Si和Ei(1 <= Si,Ei <= N)对应于卡车航线的皮卡仓库和卸货仓库。Ci(0 <= Ci <= 2000000)是关闭卡车路线的成本。
示例输入(文件milk6.in)
4 5
100 3
3 2 50
2 4 60
1 2 40
2 3 80
输出格式
输出的第一行应该是两个整数,C和t ,C是必须花费的最小值,以确保我们的牛奶永远不会到达目的地。为了实现这一目标,你计划关闭的最小的卡车线路数是T。接下来的T行应该包含一个已排序的卡车路线的索引列表,您建议关闭它。如果有多个卡车路线,以最低的成本达到目标,则选择一个关闭最少路线的路线。如果仍然有多个集合,则选择初始路由有最小索引的组。
样例输出(文件milk6.out)
60 1
3

/*
ID : mcdonne1
LANG : C++
TASK : milk6
*/

#pragma GCC optimize("O3")

#include <iostream>
#include <fstream>
#include <cstring>
#include <algorithm>

using namespace std;

struct node{
	int u, v, val, next;
}edge[1100];

int n, m, x, y, z, cnt, len, way__, ans__, sum = 0x7fffffff;
int way[35], first[35], now[1100], ans[1100], temp[1100];
bool went[35], f[1100];

inline bool __fd(int x) {
	way[++way__] = x;
	went[x] = true;
	if (x == n) return true;
	for (int i = first[x]; i; i = edge[i].next)
		if (f[i] and (!went[edge[i].v]) and __fd(edge[i].v))
			return true;
	--way__;
	return went[x] = false;
}

void find (int data) {
	int __num, __cut, __tp;
	int __ct[1100], __wy[1100];
	if (data > sum) return;
	memset (went, 0, sizeof(went));
	way__ = 0;
	if (__fd(1)) {
		__num = way__;
		memcpy (__wy, way, sizeof(way));
		for (int i = 2; i <= __num; i++) {
			__cut = __tp = 0;
			for (int p = 1; p < i; p++)
				for (int k = first[__wy[p]]; k; k = edge[k].next)
					if (f[k] and edge[k].v == __wy[i]) {
						f[k] = false;
						now[++len] = __ct[++__cut] = k;
						__tp += edge[k].val;
						if (__tp + data > sum) goto Con;
					}
			find (__tp + data);
			Con : ;
			len -= __cut;
			for (int j = 1; j <= __cut; j++)
				f[__ct[j]] = true;
		}
	} else {
		memcpy (temp, now, sizeof(now));
		sort (temp + 1, temp + 1 + len);
		if (sum > data) {
			sum = data;
			ans__ = len;
			memcpy (ans, temp, sizeof(ans));
		} else {
			if (ans__ < len) return;
			if (ans__ == len)
				for (int i = 1; i <= len; i++)
					if (ans[i] > temp[i]) break;
					else if (ans[i] < temp[i]) return;
			ans__ = len;
			memcpy (ans, temp, sizeof(ans));
		}
	}
}

int main () {
	ifstream fin("milk6.in", ios::in);
	ofstream fout("milk6.out", ios::out);
	fin>>n>>m;
	for (int i = 1; i <= m; i++) {
		fin>>x>>y>>z;
		edge[i] = (node){x, y, z, first[x]};
		first[x] = i;
	}
	memset (f, true, sizeof(f));
	find(0);
	fout<<sum<<" "<<ans__<<endl;
	for (int i = 1; i <= ans__; i++) fout<<ans[i]<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值