Description
兔纸王国中有 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。
兔纸王国中有 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;
}