兔紙王國中有 NN 個城市,第 ii 個城市和第 jj 個城市的距離是 Di,jDi,j (保證Di,j=Dj,i且Di,i=0Di,j=Dj,i且Di,i=0) 。
兔紙們使用兩種蘿蔔來修路,分別是富含胡蘿蔔素的蘿蔔和富含維生素CC的蘿蔔,單價分別是P1,P2P1,P2。由於經濟蕭條,所以兩種蘿蔔的上限分別是Q1,Q2Q1,Q2。
現在兔紙們希望修建若干條道路,使得任意兩個城市聯通。既然經濟蕭條的話,它們希望知道最小的總費用。顯而易見的,兔紙們是不會同意一條道路上存在兩種蘿蔔的。
Input Specification
第 11 行, 11 個整數 NN。
第 22 行到第 N+1N+1 行, NN 個整數Di,jDi,j。
第 N+2N+2 行, 44 個整數 P1,P2,Q1,Q2P1,P2,Q1,Q2 。
Output Specification
第 11 行, 11 個整數, 表示最小的總費用。無解則輸出 -1 。
Input and Output Sample
[input 1]
2
0 2
2 0
2 3 1 3
[output 1]
6
[input 2]
3
0 1 3
1 0 2
3 2 0
1 2 5 0
[output 2]
3
Extra Input Sample
Extra Output Sample
Data Restriction
對於 30% 的數據, 1≤N≤51≤N≤5。
對於 60% 的數據, 1≤N≤201≤N≤20。
對於 100% 的數據, 1≤N≤1,000,∀i≠j:1≤Di,j≤1,000,0≤P1,P2,Q1,Q2≤1,000,0001≤N≤1,000,∀i≠j:1≤Di,j≤1,000,0≤P1,P2,Q1,Q2≤1,000,000。
【思路】先找出最短路,然後用揹包,用bitset可以省時間和空間,其中f[ i ]表示是否有和爲i的方案
【代碼】
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#define ll long long
#define maxn 1003
#define inf 10000000000013
using namespace std;
bitset<1000006>f;
struct data{
int u,v;ll d;
bool operator<(const data&b)const{
return d<b.d;
}
}e[maxn*maxn];
int n,q1,q2,p1,p2,cnt=0,fa[maxn];
ll w[maxn],sum=0,ans;
int get(){
char c;while(!isdigit(c=getchar()));
int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48;
return v;
}
void init(){
n=get();ll x;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j){
x=get();
if(j>i){
e[++cnt].u=i;
e[cnt].v=j;
e[cnt].d=x;
}
}
q1=get(),q2=get(),p1=get(),p2=get();
sort(e+1,e+1+cnt);
}
int getfa(int x){
if(fa[x]==x)return fa[x];
else return (fa[x]=getfa(fa[x]));
}
void solveit(){
int t=0;f[0]=1;
for(int i=1;i<=n;++i)fa[i]=i;
for(int i=1;i<=cnt;++i){
int x=getfa(e[i].u),y=getfa(e[i].v);
if(x!=y){
f|=f<<e[i].d; //巧妙地位運算
sum+=e[i].d;
fa[x]=y;
--n;
}
if(n==1)break;
}
ans=(ll)inf;
for(int i=0;i<=p1;++i){
if(f[i] && (sum-i)<=p2)ans=min(ans,(ll)i*(ll)q1+(ll)(sum-i)*(ll)q2);
}
if(ans==(ll)inf)printf("-1\n");
else printf("%lld\n",ans);
}
int main(){
init();
solveit();
return 0;
}