http://acm.hdu.edu.cn/showproblem.php?pid=3339
2 2 3 0 2 9 2 1 3 1 0 2 1 3 2 1 2 1 3 1 3
5 impossible
#include <stdio.h> #include <string.h> #define INF 0x3f3f3f3f int map[220][220]; int low[220]; bool vis[220]; int N,M; int power[220]; int sum; int Dijistra() { int cnt=0; int res=0; int pos=0; int i,j; memset(vis,0,sizeof(vis)); memset(low,INF,sizeof(low)); for(i=1;i<=N;++i) { low[i]=map[0][i]; } vis[0]=1; low[0]=0; for(i=1;i<=N;++i) { int min=INF; for(j=0;j<=N;++j) { if(!vis[j]&&min>low[j]) { min=low[j]; pos=j; } } if(min==INF) return -1; vis[pos]=1; cnt+=power[pos]; if(cnt>sum/2) return low[pos]; for(j=1;j<=N;++j) { if(!vis[j]&&low[j]>map[pos][j]+low[pos]) { low[j]=map[pos][j]+low[pos]; } } } return -1; } int main() { int T; int u,v,w; scanf("%d",&T); while(T--) { scanf("%d%d",&N,&M); memset(map,INF,sizeof(map)); while(M--) { scanf("%d%d%d",&u,&v,&w); if(map[u][v]>w) map[u][v]=map[v][u]=w; } sum=0; for(int i=1;i<=N;++i) { scanf("%d",power+i); sum+=power[i]; } int ans=Dijistra(); if(ans==-1) printf("impossible\n"); else printf("%d\n",ans); } return 0; }
#include <stdio.h> #include <string.h> #define min(a,b) (a<b?a:b) #define INF 0x3f3f3f3f int dp[210010]; int map[220][220]; int low[220]; bool vis[220]; int N,M; int power[220]; int sum; int Dijistra() { int pos=0; int i,j; memset(vis,0,sizeof(vis)); memset(low,INF,sizeof(low)); for(i=1;i<=N;++i) { low[i]=map[0][i]; } vis[0]=1; low[0]=0; for(i=1;i<=N;++i) { int min=INF; for(j=0;j<=N;++j) { if(!vis[j]&&min>low[j]) { min=low[j]; pos=j; } } // if(min==INF) return -1; vis[pos]=1; // cnt+=power[pos]; // if(cnt>sum/2) return low[pos]; for(j=1;j<=N;++j) { if(!vis[j]&&low[j]>map[pos][j]+low[pos]) { low[j]=map[pos][j]+low[pos]; } } } // return -1; } int main() { int T; int u,v,w; int i,j; scanf("%d",&T); while(T--) { scanf("%d%d",&N,&M); memset(map,INF,sizeof(map)); while(M--) { scanf("%d%d%d",&u,&v,&w); if(map[u][v]>w) map[u][v]=map[v][u]=w; } sum=0; for(i=1;i<=N;++i) { scanf("%d",power+i); sum+=power[i]; } Dijistra(); for(i = 1; i<=sum; i++) dp[i] = INF; dp[0] = 0; for(i = 1; i<=N; i++)//01背包找出最小油耗量 { for(j = sum; j>=power[i]; j--) dp[j] = min(dp[j],dp[j-power[i]]+low[i]); } int x = sum/2+1;//必须大于一半,等于都不行 int minn = INF; for(i = x; i<=sum; i++) { if(dp[i]<minn) minn = dp[i]; } if(minn == INF) printf("impossible\n"); else printf("%d\n",minn); } return 0; }