Kingdoms
Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 410 Solved: 127
[Submit][Status][Web Board]
Description
Input
Output
For each test case, print the maximal accessible population.
Sample Input
2
4 6 6
500 400 300 200
1 2 4
1 3 3
1 4 2
4 3 5
2 4 6
3 2 7
4 6 5
500 400 300 200
1 2 4
1 3 3
1 4 2
4 3 5
2 4 6
3 2 7
Sample Output
1100
1000
HINT
Source
题意:有m条可修复的路,每个城市有相应的人口数,修复每条路需要指定的话费,问你在话费不超过K,最多能与多少人相通(可以当作能获取多少资源)
解题思路:比赛时,由于到最后一个小时才接到这题,思路很混乱就开始上去写了,比赛时将代码写戳了。言归正传:
我们可以用二进制状态表示访问的每种情况,比如1010,表示城市二和四被访问了,然后我们只要建立相应的状态转移方程即可。
<span style="font-size:18px;">#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
const int N=17;
int map[N][N];
int value[N];
int dp[1<<N];
int main()
{
int n,m,l;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d %d",&n,&m,&l);
int x,y,dis;
memset(map,0x3f,sizeof(map));
for(int i=1;i<=n;i++) scanf("%d",&value[i]);
for(int i=0;i<m;i++){
scanf("%d %d %d",&x,&y,&dis);
map[y][x]=map[x][y]=min(map[x][y],dis);
}
memset(dp,0x3f,sizeof(dp));
dp[1]=0;
for(int i=2;i<(1<<n);i++) ///状态
{
if(i&1){
for(int j=1;j<=n;j++){
if(i &(1 <<(j-1))){
for(int k=1;k<=n;k++){
if(i &(1 <<(k-1))){
dp[i]=min(dp[i],dp[i &(~(1 <<(k-1)))]+map[k][j]);
}
}
}
}
}
}
int ans=0;
for(int i=1;i<(1<<n);i++)
{
int sum=0;
if(dp[i]<=l){
for(int j=1;j<=n;j++){
if(i &(1 <<(j-1)))
sum+=value[j];
}
}
ans=max(ans,sum);
}
printf("%d\n",ans);
}
return 0;
}
</span>