题目一开始题都没读懂,“maximum adjacent distance”把我给整懵了。。。
题意:给一个图,图中一些点有黄金,一些点有放黄金的仓库,但有容量限制,问把所有黄金都能装进仓库的路径中权值最大的那条路是多少。
思路:这道题可以用并查集,先记录输出黄金的城市个数num,并用sum[i]表示第i个点是输出黄金还是输入黄金,把黄金所有量或者仓库存储量都给并查集的头,在合并的时候,出现了输出城市减少的情况,则num-1,直到num=0,num不能为0则是不可能。开始以为只有一辆车来运,想着合成一个集合就可以,但是后来发现可以多辆车同时搞,也就是完成任务时可能有多个集合,所以采用记录输出黄金城市个数的方式。
//对于输出城市减少的情况讨论:
//合并时无非只有以下四种情况,分别对应的结果如下
/*******************************/
//结点 父亲 儿子 结果
//sum值 >0(输出) <0(输入) 当sum[父亲] + sum[儿子] <= 0的时候 num-- (少了父亲这个城市)
//sum值 <0(输入) >0(输出) 当sum[父亲] + sum[儿子] <= 0的时候 num-- (少了儿子0这个城市)
//sum值 >0(输出) >0(输出) num-- (少了儿子这个城市)
//sum值 <0(输入) <0(输入) num不变
/*******************************/
//#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define mod (10007)
#define middle (l+r)>>1
#define SIZE 1000000+5
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long ll;
typedef long double ld;
const int inf_max = 0x3f3f3f;
const ll Linf = 9e18;
const int maxn = 200 + 10;
const long double E = 2.7182818;
const double eps=0.0001;
using namespace std;
inline int read()
{
int f=1,res=0;
char ch=getchar();
while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') { res=res*10+ch-'0' ; ch=getchar(); }
return f*res;
}
struct EDG {
int v,u,val;
bool operator<(const EDG &a)const {
return val < a.val;
}
}edge[maxn*maxn];
int n,m,tot,fa[maxn],cnt,ans,sum[maxn],num; sum[i]为正代表还有黄金输出
void Initial() {
for(int i = 1;i <= n; ++i) fa[i] = i;
memset(edge,0,sizeof(edge));
memset(sum,0,sizeof(sum));
cnt = ans = num = 0;
}
void add_edge(int u,int v,int val) {
edge[cnt].val = val;
edge[cnt].v = v;
edge[cnt++].u = u;
}
int Find(int x) {
if(fa[x] == x) return fa[x];
return fa[x] = Find(fa[x]);
}
int main()
{
while(scanf("%d",&n),n) {
Initial();
for(int i = 1;i <= n; ++i) {
int tt = read();
sum[i] += tt;
}
for(int i = 1;i <= n; ++i) {
int tt = read();
sum[i] -= tt;
if(sum[i] > 0) num++;
}
m = read();
for(int i = 1;i <= m; ++i) {
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].val);
}
sort(edge + 1,edge + 1 + m);
for(int i = 1;i < m; ++i) {
int u = edge[i].u,v = edge[i].v,val = edge[i].val;
int fu = Find(u),fv = Find(v);
if(fu != fv) {
int minf = min(fu,fv),maxf = max(fu,fv),cur = sum[minf] + sum[maxf];
fa[maxf] = minf;
if(sum[maxf] > 0 && sum[minf] > 0) num--;
else if(sum[minf] * sum[maxf] < 0 && cur <= 0) num--;
sum[minf] = cur;
if(num == 0) {
printf("%d\n",val);
break;
}
}
}
if(num) printf("No Solution\n");
}
return 0;
}