首页 > 代码库 > HDU 4848 - Wow! Such Conquering!

HDU 4848 - Wow! Such Conquering!

首先Floyd算法得到任意两点间的最短时间;

然后之间进行DFS,剪枝优化时间。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define MAXN 33
 5 #define INF 0x3f3f3f3f
 6 using namespace std;
 7 int d[MAXN][MAXN],ans;
 8 int n,deadline[MAXN],arrival_time[MAXN];
 9 bool vis[MAXN];
10 void floyd()
11 {
12     for(int k=1;k<=n;k++)
13     {
14         for(int i=1;i<=n;i++)
15         {
16             for(int j=1;j<=n;j++) d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
17         }
18     }
19 }
20 void dfs(int now,int cur_time,int sum_time,int cnt)  
21 {  
22     if(cnt==n)//走完了n个星球 
23     {
24         ans=min(ans,sum_time);//尝试更新答案,使得答案是到目前为止的最优解
25         return;
26     }
27     
28     if(sum_time + cur_time * (n-cnt) >= ans) return;
29         //最优性剪枝:当前到达时间和 + 当前时间 * 还没去的星球 >= 到目前为止的最优解,剪掉 
30         //      因为,到目前为止,还没去的星球,到达那里的时间必然大于等于当前时间
31         
32     for(int i=2;i<=n;i++) if(!vis[i] && cur_time>deadline[i]) return;
33          //可行性剪枝:到目前为止,现在的时间大于未到达的星球的deadline,已经不满足要求,剪掉 
34          
35     for(int next=1;next<=n;next++)  
36     {  
37         if(now!=next && !vis[next] && cur_time+d[now][next]<=deadline[next])
38         {  
39             vis[next]=1;
40             dfs(next,cur_time+d[now][next],sum_time+cur_time+d[now][next],cnt+1);
41             vis[next]=0;
42         }  
43     }  
44   
45 } 
46 int main()
47 {
48     while(scanf("%d",&n)!=EOF)
49     {
50         for(int i=1;i<=n;i++)
51             for(int j=1;j<=n;j++)
52             {
53                 scanf("%d",&d[i][j]);
54             }
55             
56         for(int i=2;i<=n;i++) scanf("%d",&deadline[i]);
57         deadline[1]=INF;
58         
59         floyd(); 
60         
61         ans=INF;
62         vis[1]=1;
63         dfs(1,0,0,1);
64         printf("%d\n", ((ans==INF)?-1:ans) );
65     }
66 } 

 

HDU 4848 - Wow! Such Conquering!