AcWing 1135. 新年好

原题链接

考察:最短路+dfs

本题的正解思路想到了...但是感觉不可能放弃了....以后要戒掉感觉不可能的这个词

思路:

       由于五个点都要到达.当我们从起点到达其中一个点后,剩下的就是求点与点之间的最短距离.这里直接预处理点与点之间的最短距离.再枚举到达点的顺序.不必担心到达某个点的途中去过了另一个点.因为dfs全排列会枚举所有到达点的顺序.当前枚举顺序不一定是正解.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <queue>
 4 using namespace std;
 5 const int N = 50010,M = 100010,S = 6;
 6 typedef pair<int,int> PII;
 7 int n,m,a[S],idx,h[N],dist[S][N],path[S+10],ans =0x3f3f3f3f;
 8 bool st[N];
 9 struct Road{
10     int to,ne,w;
11 }road[M<<1];
12 void add(int a,int b,int w)
13 {
14     road[idx].to = b,road[idx].w = w,road[idx].ne = h[a],h[a] = idx++;
15 }
16 void dijkstra(int s)
17 {
18     priority_queue<PII,vector<PII>,greater<PII> > q;
19     memset(dist[s],0x3f,sizeof dist[s]);
20     memset(st,0,sizeof st);
21     dist[s][a[s]] = 0;
22     q.push({0,a[s]});
23     while(q.size())
24     {
25         PII it = q.top();
26         q.pop();
27         int u = it.second;
28         if(st[u]) continue;
29         st[u] = 1;
30         for(int i=h[u];~i;i=road[i].ne)
31         {
32             int v = road[i].to;
33             if(dist[s][v]>dist[s][u]+road[i].w)
34             {
35                 dist[s][v] = dist[s][u]+road[i].w;
36                 q.push({dist[s][v],v});
37             }
38         }
39     }
40 }
41 void dfs(int cnt)
42 {
43     if(cnt>=5)
44     {
45         int res = dist[0][a[path[0]]];
46    //     for(int i=0;i<5;i++) printf("%d ",a[path[i]]);
47     //    printf("\n");
48         for(int i=0;i<4;i++)
49           res+=dist[path[i]][a[path[i+1]]];
50         ans = min(res,ans);
51         return;
52     }
53     for(int i=1;i<=5;i++)
54       if(!st[i])
55       {
56           path[cnt] = i;
57           st[i] = 1;
58           dfs(cnt+1);
59           st[i] = 0;
60       }
61 }
62 int main()
63 {
64     scanf("%d%d",&n,&m);
65     memset(h,-1,sizeof h);
66     a[0] = 1;
67     for(int i=1;i<=5;i++) scanf("%d",&a[i]);
68     while(m--)
69     {
70         int a,b,w; scanf("%d%d%d",&a,&b,&w);
71         add(a,b,w); add(b,a,w);
72     }
73     for(int i=0;i<=5;i++) dijkstra(i);
74     memset(st,0,sizeof st);
75     dfs(0);
76     printf("%d\n",ans);
77     return 0;
78 }

 

posted @ 2021-04-27 14:46  acmloser  阅读(48)  评论(0编辑  收藏  举报