列表

详情


NC15331. Collect Jewel

描述

There is a mystical country on the magic continent.
There are N jewel caves and M directed roads connecting these caves in the country. The caves are numbered from 1 to N, and the ith cave has Ai jewels. The roads are numbered from 1 to M, the ith road connects the cave from Ui to Vi.

The King loves jewel very much, so he wants to dispatch no more than K soldiers to the jewel caves to collect jewels.

Firstly, the King will give each soldier a unique route. Then, each soldier will be transferred to the starting point of his unique route. And they will follow the route to collect the jewels until they arrive at the end of the route. Finally, they will go back to the King by air and give all the jewels they collected to the King.

After a soldier arrives at a jewel cave, he will take all the jewels in the cave away. However, because of the harassment of the robbers in the route, when the soldier passes through the ith road he will pay Ci jewels to the robbers. At any time, the number of jewels on the soldier could be zero and even negative.

Please help the King setting up routes for every soldier to collect jewels as much as possible.


输入描述

The first line contains an integer T, where T is the number of test cases. T test cases follow.

For each test case, the first line contains three integers N, M and K, where N is the number of jewel caves, M is the number of roads and K is the number of soldiers that the King could dispatch at most. 
The second line contains N integers A1, A2, ... , AN, where Ai is the number of jewels in the ith cave.
Then M lines followed, each line contains three integers Ui, Vi and Ci, indicating there is a road connectsthe cave from Ui to Vi and when the soldiers pass through the road he should pay Ci jewels.

• 1 ≤ T ≤ 10.
• 1 ≤ N ≤ 102.
• 0 ≤ M ≤ 103.
• 1≤ K ≤105

• 0≤ Ai,Ci ≤104
• 1 ≤ Ui < Vi ≤ N.

输出描述

For each test case, print one line containing “Case #x: y”, where x is the test case number (starting from
1) and y is the largest number of jewels the King could get.

示例1

输入:

2
2 1 1
3 4
1 2 2
4 5 2
5 6 2 3
1 2 1
1 3 2
2 3 3
1 4 4
3 4 5

输出:

Case #1: 5
Case #2: 13

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 58ms, 内存消耗: 504K, 提交时间: 2019-06-21 11:26:09

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define ba 47
#define MAXN 1000005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
	if(c == '-') f = -1;
	c = getchar();
    }
    while(c >= '0' && c <= '9') {
	res = res * 10 +c - '0';
	c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
	out(x / 10);
    }
    putchar('0' + x % 10);
}
struct node {
    int to,next,cap,val;
}E[MAXN];
int head[305],sumE;
int Ncnt,st[105],ed[105],S,T,N,M,K,a[105];
void add(int u,int v,int c,int a) {
    E[++sumE].to = v;
    E[sumE].cap = c;
    E[sumE].val = a;
    E[sumE].next = head[u];
    head[u] = sumE;
}
void addtwo(int u,int v,int c,int a) {
    add(u,v,c,a);add(v,u,0,-a);
}
int dis[305],preE[305];
bool inq[305];
queue<int> Q;
bool SPFA() {
    for(int i = 1 ; i <= Ncnt; ++i) dis[i] = -1e9;
    memset(inq,0,sizeof(inq));
    dis[S] = 0;inq[S] = 1;Q.push(S);
    while(!Q.empty()) {
	int u = Q.front();Q.pop();inq[u] = 0;
	for(int i = head[u] ; i ; i = E[i].next) {
	    int v = E[i].to;
	    if(E[i].cap > 0 && dis[v] < dis[u] + E[i].val) {
		dis[v] = dis[u] + E[i].val;
		preE[v] = i;
		if(!inq[v]) {
		    Q.push(v);inq[v] = 1;
		}
	    }
	}
    }
    return dis[T] > 0;
}
void Solve() {
    memset(head,0,sizeof(head));sumE = 1;
    Ncnt = 0;
    read(N);read(M);read(K);
    for(int i = 1 ; i <= N ; ++i) {
	read(a[i]);
	st[i] = ++Ncnt;ed[i] = ++Ncnt;
	addtwo(st[i],ed[i],1,a[i]);addtwo(st[i],ed[i],1e9,0);
    }
    int u,v,c;
    for(int i = 1 ; i <= M ; ++i) {
	read(u);read(v);read(c);
	addtwo(ed[u],st[v],1e9,-c);
    }
    S = ++Ncnt;T = ++Ncnt;
    for(int i =  1 ; i <= N ; ++i) {
	addtwo(S,st[i],1e9,0);
	addtwo(ed[i],T,1e9,0);
    }
    int ans = 0;
    while(K--) {
	if(!SPFA()) break;
	int p = T;
	while(p != S) {
	    int t = preE[p];
	    E[t].cap -= 1;
	    E[t ^ 1].cap += 1;
	    p = E[t ^ 1].to;
	}
	ans += dis[T];
    }
    out(ans);enter;
}
int main(){
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    int T;
    read(T);
    for(int i = 1 ; i <= T ; ++i) {
	printf("Case #%d: ",i);
	Solve();
    }
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 37ms, 内存消耗: 616K, 提交时间: 2018-04-29 23:02:25

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=205,M=4e3+5,INF=0x3f3f3f3f;
int he[N],ver[M],nex[M],C[M],co[M],tot;
inline void add(int,int,int,int);
int pre[N],d[N],tag[N],s,t,cost,maxflow;
bool spfa();
void update();
int T,n,m,k,u,v,w,c;
int a[N],deg[N];
int main(){
	int ca=1;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d%d",&n,&m,&k);
		memset(he,0,sizeof(he));tot=2;
		s=0,t=2*n+1;
		int ss=t+1;
		add(s,ss,k,0);
		for(int i=1;i<=n;i++) scanf("%d",a+i);
		for(int i=1;i<=n;i++)
			add(i,i+n,1,-a[i]),add(i,i+n,INF,0),add(ss,i,INF,0),add(i+n,t,INF,0);
		memset(deg,0,sizeof(deg));
		for(int i=0;i<m;i++){
			scanf("%d%d%d",&u,&v,&c);
			add(u+n,v,INF,c);
		}
		cost=maxflow=0;
		while(spfa()) update();
		printf("Case #%d: %d\n",ca++,-cost);
	}
	return 0;
}
void update(){
	int x=t,i;
	int Max=INF;
	while(x!=s){
		i=pre[x];
		Max=min(Max,C[i]);
		x=ver[i^1];
	}
	x=t;
	while(x!=s){
		i=pre[x];
		C[i]-=Max;
		C[i^1]+=Max;
		x=ver[i^1];
	}
	maxflow+=Max;
	cost+=Max*d[t];
}
bool spfa(){
	memset(d,0x3f,sizeof(d));
	memset(tag,0,sizeof(tag));
	d[s]=0;
	queue<int>q;
	q.push(s);
	while(!q.empty()){
		int u=q.front();q.pop();
		tag[u]=0;
		for(int i=he[u];i;i=nex[i]){
			int v=ver[i];
			if(C[i]&&d[v]>d[u]+co[i]){
				d[v]=d[u]+co[i];
				pre[v]=i;
				if(!tag[v]){
					tag[v]=1;q.push(v);
				}
			}
		}
	}
	return d[t]!=INF;
}
void add(int u,int v,int w,int c){
	ver[tot]=v;nex[tot]=he[u];C[tot]=w;co[tot]=c;he[u]=tot++;
	ver[tot]=u;nex[tot]=he[v];C[tot]=0;co[tot]=-c;he[v]=tot++;
}

上一题