**Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5762 Accepted Submission(s): 1857
**
Problem Description
After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best choice!He has decided to visit n cities(he insists on seeing all the cities!And he does not mind which city being his start station because superman can bring him to any city at first but only once.), and of course there are m roads here,following a fee as usual.But Mr Acmer gets bored so easily that he doesn't want to visit a city more than twice!And he is so mean that he wants to minimize the total fee!He is lazy you see.So he turns to you for help.
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
题意:有N个城市,一个人要 经过每个点,且经过每个点不超过2次。求最少的路费。可以从任意一个点开始。
思路:TSP,这个是三进制的状态压缩,因为过每个点要求不超过两次,其余dp的思路和TSP二进制差不多,可以说一样。
dp[i][j]表示在状态i下以j点结束的所要的最小费用。 dp[i][j]=min(dp[i][j],dp[cc][v]+ma[v][j]);cc,表示i的上一个状态。
代码:
1 #include 0)//判断上个状态是否经过上个状态的结束点
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 typedef long long ll;
9 long long ma[20][20];
10 long long dp[60000][20];//开pow(3,11);
11 long long san[60000][20];
12 int a[60000];//记录状态是否都至少经过一次
13 const long long N=1e9;
14 using namespace std;
15 int main(void)
16 {
17 long long n,i,j,k,p,q;
18 long long x,y,v;
19 memset(san,0,sizeof(san));
20 for(i=0; i<60000; i++)
21 {
22 ll vv=i;
23 int flag=0;
24 int f=0;
25 while(vv)
26 {
27 san[i][f++]=vv%3;
28 if(vv%3==0)
29 {
30 flag=1;
31 }
32 vv/=3;
33
34 }
35 if(flag==0) a[i]=1;
36 }//把状态用三进制表示
37 while(scanf("%lld %lld",&p,&q)!=EOF)
38 {
39 for(i=0; i<20; i++)
40 for(j=0; j<20; j++)
41 ma[i][j]=N;
42 for(i=0; i<60000; i++)
43 for(j=0; j<20; j++)
44 dp[i][j]=N;
45 for(i=0; i0)//判断当前状态是否经过这点
68 {
69 int uu=0;
70 int rr=1;
71 for(v=0; v
85 {
86 dp[i][j]=min(dp[i][j],dp[uu][v]+ma[v][j]);
87
88 }
89 }
90 }
91 }
92
93 }
94 long long minn=N;
95 int tu=0;
96 for(i=0; i<p; i++)
97 {
98 tu*=3;
99 tu+=1;
100 }
101 for(i=tu; i<yy; i++)//至少经过每个点一次中取最小
102 {
103 if(a[i])
104 {
105 for(j=0; j<p; j++)
106 {
107 if(dp[i][j]<minn)
108 {
109 minn=dp[i][j];
110 }
111
112 }
113 }
114
115 }
116
117 if(minn==N)
118 {
119 printf("-1\n");
120 }
121 else
122 printf("%lld\n",minn);
123 }
124 return 0;
125 }
手机扫一扫
移动阅读更方便
你可能感兴趣的文章