題目一開始題都沒讀懂,“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;
}