Input There are several test cases,the first line is two intergers n(1<=n<=10) and m,which means he needs to visit n cities and there are m roads he can choose,then m lines follow,each line will include three intergers a,b and c(1<=a,b<=n),means there is a road between a and b and the cost is of course c.Input to the End Of File.
Output Output the minimum fee that he should pay,or -1 if he can't find such a route.
Sample Input
2 1 1 2 100 3 2 1 2 40 2 3 50 3 3 1 2 3 1 3 4 2 3 10
Sample Output
100 90 7
?
看了别人的思路,自己写出来了:)。这题和poj3311差不多,但是不能用floyd处理,因为它有访问次数限制,最多相同的地方访问两次,至少一次,所以为了存储状态,我们可以用三进制表示,1代表访问一次,2代表访问2次。动态转移方程也和之前的差不多,为dp[s][i]=min(dp[s][i],dp[s-san[i-1]][j]+dis[j][i])。最后的结论要在访问过程中产生,如果当前所枚举的状态符合用三进制表示后每一位的数都大于0,那么就表示都访问到了,就可以和所求的结果ans比,如果比ans小就更新。
?
#include#include #define inf 88888888 int dis[15][15],dp[200000][15],wei[15],num,t; int san[15]={1,3,9,27,81,243,729,2187,6561,19683,59049,177147}; int min(int a,int b){ return a 0){ if(x%3>0)num++; wei[++t]=x%3; x=x/3; } } int main() { int n,m,i,j,a,b,c,s,ans; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ dis[i][j]=inf; } } for(i=1;i<=m;i++){ scanf("%d%d%d",&a,&b,&c); if(dis[a][b]>c)dis[a][b]=dis[b][a]=c; } ans=inf; for(s=1;s =i && wei[t]>0){ if(s==san[i-1]){ dp[s][i]=0; } else{ for(j=1;j<=n;j++){ if(j!=i && wei[j]>0){ dp[s][i]=min(dp[s][i],dp[s-san[i-1]][j]+dis[j][i]); if(num==n){ ans=min(ans,dp[s][i]); } } } } } } if(ans==0)break; } if(ans==inf)printf("-1\n"); else printf("%d\n",ans); } }
?