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>