HDU 6166 Senior Pan

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6166

题意:

  给一张n个点m条边的有向图(1≤n,m≤100000),然后给一大波点设为集合V,问V内两点的最短距离。

题解:

  看到这题的时候想设一个超级源点,连上V内的点,一个超级汇点连上V内的点且距离都为0,也就是求超级源点和汇点的最短路了,然后又一想如果源点连的点和汇点连的点一样不就GG了吗。
  然后就是解决这个问题,我们能不能做下标记使其源点连的点和汇点连的不一样,那么维护一个from就可以了,怎么维护呢,其实就是次短路,考虑源点出去两条最短的路线(其实就是最短路和次短路)到经过某一点到终点所连的点,如果这其中某一条路径和终点连的点重合了,那么就用另外一个点作为源点所连的点就行了,那么对于V里的任一点u也一样,源点到这些点的最短路径其实就是0,from是u本身,如果有一条源点不是u的最短路就行了,不就是次短路吗?比赛的时候900+ms水过。。

比赛完了信心满满的去看题解然后说是类似于CF的835E,通过什么玄学的东西搞的(没仔细看,水过就行了),那种方法的复杂度是20*dijkstra,好久没打过CF了。。。。。

比赛时候在队友电脑上写的代码变量命名,文件啥的有点乱。。。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 const long long INF=1e18;
 5 const int maxn=100000+10;
 6 typedef long long ll;
 7 typedef pair<ll, ll> pii;
 8 int T,u,v,w,n,m,k,cc;
 9 bool vis[maxn];
10 struct node {
11     int v,w;
12     node() {}
13     node(int a, int b) {v=a;w=b;}
14 };
15 struct tnode {
16     int v;long long d; int f;
17     tnode(){}
18     tnode(int a,long long b,int c){v=a;d=b;f=c;}
19     bool operator < (const tnode& a) const {
20         return d>a.d;
21     }
22 };
23 int from[maxn][2];
24 long long d[maxn][2];
25 vector<node> g[maxn];
26 void dik () {
27     priority_queue<tnode>que;
28     for(int i=1;i<=n;++i){
29         if(vis[i]) {
30             que.push(tnode(i,0,i));
31         }
32     }
33     while(!que.empty()) {
34         tnode p=que.top();que.pop();
35         int v=p.v; long long ds=p.d;
36         if(d[v][1]<ds)continue;
37         for(auto x:g[v]) {
38             long long d2=ds+x.w; int tfs=p.f;
39             if(d[x.v][0]>d2) {
40                 swap(d[x.v][0],d2);
41                 swap(tfs,from[x.v][0]);
42                 que.push(tnode(x.v,d[x.v][0],from[x.v][0]));
43             }
44             if(d[x.v][1]>d2&&tfs!=from[x.v][0]) {
45                 d[x.v][1]=d2;
46                 from[x.v][1]=tfs;
47                 que.push(tnode(x.v,d[x.v][1],from[x.v][1]));
48             }
49 
50         }
51     }
52 }
53 int main() {
54 #ifdef __AiR_H
55     freopen("1001.in", "r", stdin);
56 #endif // __AiR_H
57     scanf("%d",&T);
58     while(T--) {
59         scanf("%d%d",&n,&m);
60         for(int i=1;i<=n;++i) {
61             g[i].clear();
62         }
63         for(int i=1;i<=m;++i) {
64             scanf("%d%d%d",&u,&v,&w);
65             g[u].push_back(node{v,w});
66         }
67 
68         memset(vis,0,sizeof(vis));
69         scanf("%d",&k);
70         for(int i=1;i<=k;++i) {
71             scanf("%d",&u); vis[u]=1;
72         }
73         for(int i=1;i<=n;++i) {
74             if(!vis[i]) {
75                 from[i][0]=0;
76                 from[i][1]=0;
77                 d[i][1]=INF;
78                 d[i][0]=INF;
79             }
80             else {
81                 from[i][0]=i;
82                 from[i][1]=0;
83                 d[i][0]=0;
84                 d[i][1]=INF;
85             }
86         }
87         dik();
88         long long ans=INF;
89         for(int i=1;i<=n;++i) {
90             if(vis[i]) {
91 
92                 ans=min(ans,d[i][1]);
93             }
94         }
95         printf("Case #%d: %lld\n",++cc,ans);
96     }
97     return 0;
98 }
View Code

 

posted on 2017-08-22 19:25  仰望咸鱼Orzzzz  阅读(292)  评论(0编辑  收藏  举报

导航