1. 程式人生 > >hdu 6166 Senior Pan

hdu 6166 Senior Pan

jks != pan ini 同時 mat stdin line help

地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6166

題目:

Senior Pan

Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 245 Accepted Submission(s): 71


Problem Description Senior Pan fails in his discrete math exam again. So he asks Master ZKC to give him graph theory problems everyday.
The task is simple : ZKC will give Pan a directed graph every time, and selects some nodes from that graph, you can calculate the minimum distance of every pair of nodes chosen in these nodes and now ZKC only cares about the minimum among them. That is still too hard for poor Pan, so he asks you for help.

Input The first line contains one integer T, represents the number of Test Cases.1≤T≤5.Then T Test Cases, for each Test Cases, the first line contains two integers n,m representing the number of nodes and the number of edges.1≤n,m≤100000
Then m lines follow. Each line contains three integers xi,yi representing an edge, and vi
representing its length.1≤xi,yi≤n,1≤vi≤100000
Then one line contains one integer K, the number of nodes that Master Dong selects out.1≤K≤n
The following line contains K unique integers ai, the nodes that Master Dong selects out.1≤ai≤n,ai!=aj

Output For every Test Case, output one integer: the answer

Sample Input 1 5 6 1 2 1 2 3 3 3 1 3 2 5 1 2 4 2 4 3 1 3 1 3 5

Sample Output Case #1: 2

Source 2017 Multi-University Training Contest - Team 9 思路:   官方題解看的有點迷,看了半天才懂。   就是把k個關鍵點分為兩個點集st,se,兩個點集間的最短距離可以通過兩次dijkstra或者spfa求出來。   所以現在的關鍵問題是怎麽劃分點集,使得任意點對都會被劃分到不同點集中。   一次劃分顯然是不可能的,所以可進行有限次劃分滿足上面的要求。   考慮到任意不同數對x,y。x,y在二進制下必有一位不相同。   所以可以通過二進制位進行20次劃分,這樣就可以覆蓋所有情況。   同時還有一種隨機做法,就是進行t次random_shuffle用來劃分點集。
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define MP make_pair
 6 #define PB push_back
 7 typedef long long LL;
 8 typedef pair<int,int> PII;
 9 const double eps=1e-8;
10 const double pi=acos(-1.0);
11 const int K=1e5+7;
12 const int mod=1e9+7;
13 
14 vector<PII >mp[K];
15 vector<int>key,st,se;
16 LL dis[K];
17 int n,m,k;
18 
19 LL spfa(vector<int> &s,vector<int> &e)
20 {
21     queue<int>q;
22     fill(dis+1,dis+n+1,1e12);
23     for(auto &x:s)
24         q.push(x),dis[x]=0;
25     while(q.size())
26     {
27         int u=q.front();q.pop();
28         for(auto &v:mp[u])
29         if(dis[v.first]>dis[u]+v.second)
30         {
31             dis[v.first]=dis[u]+v.second;
32             q.push(v.first);
33         }
34     }
35     LL ret=1e15;
36     for(auto &x:e)
37         ret=min(ret,dis[x]);
38     return ret;
39 }
40 int main(void)
41 {
42     //freopen("in.acm","r",stdin);
43     int t,cs=1;cin>>t;
44     while(t--)
45     {
46         memset(mp,0,sizeof mp);
47         key.clear();
48         LL ans=1e15;
49         scanf("%d%d",&n,&m);
50         for(int i=1,x,y,z;i<=m;i++)
51             scanf("%d%d%d",&x,&y,&z),mp[x].PB(MP(y,z));
52         scanf("%d",&k);
53         for(int i=1,x;i<=k;i++)
54             scanf("%d",&x),key.PB(x);
55         for(int i=0;i<=20;i++)
56         {
57             st.clear(),se.clear();
58             for(auto &x:key)
59             if(x&(1<<i))
60                 st.push_back(x);
61             else
62                 se.push_back(x);
63             ans=min(ans,min(spfa(st,se),spfa(se,st)));
64         }
65         printf("Case #%d: %lld\n",cs++,ans);
66     }
67     return 0;
68 }

hdu 6166 Senior Pan