Meeting HDU - 5521
生活随笔
收集整理的這篇文章主要介紹了
Meeting HDU - 5521
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Meeting HDU - 5521
題意:
一共有n個點,有m個塊,每個塊內有Si個點,塊內點彼此到達費用為wi,兩個人分別位于1和n號塊,兩者同時出發問最短時間遇到是多少?在哪些地方可以遇到?
ΣSi<=106
題解:
題意很明確,我們需要先建邊,然后從點1開始跑最短路得到dis[i],再從點n跑最短路得到dist[i]
dis[i]表示第1個點到第i個點的最短距離
dist[i]表示第n個點到第i個點的最短距離
答案就是minn= min(max(dis[i],dist[i]),minn)
因為兩者同時出發,所以時間取長者,然后找最短時間所以取min
題目難度在于ΣSi<=106,如果你按照塊內所有點兩兩建邊,那復雜度肯定暴力。(考慮極端情況所有點在一個塊內),那怎么解決?我們可以在塊外建議一個新點x,讓塊內所有點與其相連,邊權不變,這樣任意兩個點都可以通過這個x中間點實現連接,這樣就巧妙建邊(會網絡流的應該好理解,相當于一個人造源點)
建議不要用ios::sync_with_stdio(0);玄學錯誤,導致我wa了八次
代碼:
#include <bits/stdc++.h> using namespace std; #define asd cout<<" SB "<<endl; #define ll long long #define ull unsigned long long #define INF 0x3f3f3f3f const int maxn=1e6+9; struct node{int v;int c;node(int v=0,int c=0):v(v),c(c){}bool operator<(const node &r)const{return c>r.c;} }; struct cmp{int x;cmp(int x=0):x(x){}bool operator<(const cmp &r)const{return x>r.x;} }; struct Edge{int v,cost;Edge(int _v=0,int _cost=0):v(_v),cost(_cost){} }; vector<Edge>E[maxn]; bool vis[maxn]; int dist[maxn]; int dis[maxn]; void dij(int n,int start){memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++)dist[i]=INF;priority_queue<node>q;while(!q.empty())q.pop();dist[start]=0;q.push(node(start,0));node tmp;while(!q.empty()){tmp=q.top();q.pop();int u=tmp.v;if(vis[u])continue;vis[u]=1;for(int i=0;i<E[u].size();i++){int v=E[tmp.v][i].v;int cost=E[u][i].cost;if(!vis[v]&&dist[v]>dist[u]+cost){dist[v]=dist[u]+cost;q.push(node(v,dist[v]));}}} } int main(){ios::sync_with_stdio(0);int t;cin>>t;int cas=0;while(t--){memset(E,0,sizeof(E));int n,m;cin>>n>>m; // for(int i=1;i<=n;i++)dis[i]=INF;int tot=0;for(int i=1;i<=m;i++){int w;cin>>w;int S;cin>>S;for(int j=1;j<=S;j++){int x;cin>>x;// printf("u=%d v=%d w=%d\n",n+i,x,w);E[n+i].push_back(Edge(x,w));E[x].push_back(Edge(n+i,w));}} // for(int i=n+1;i<=n+m;i++){ // for(int j=i+1;j<=n+m;j++){ // printf("u=%d v=%d w=%d\n",i,j,0); // E[i].push_back(Edge(j,0)); // E[j].push_back(Edge(i,0)); // } // }dij(n+m,1);for(int i=1;i<=n;i++)dis[i]=dist[i];dij(n+m,n);int minn=INF;for(int i=1;i<=n;i++)minn=min(minn,max(dis[i],dist[i]));if(minn==INF){printf("Case #%d: Evil John\n",++cas);continue;}priority_queue<cmp>q;for(int i=1;i<=n;i++){if(max(dis[i],dist[i])==minn){q.push(i);}}bool f=0;printf("Case #%d: %d\n",++cas,minn/2);while(!q.empty()){if(f==0)printf("%d",q.top().x);else printf(" %d",q.top().x);q.pop();f=1;}printf("\n");}return 0; } /* 2 5 4 1 3 1 2 3 2 2 3 4 3 2 1 5 3 3 3 4 5 3 1 1 2 1 2 */總結
以上是生活随笔為你收集整理的Meeting HDU - 5521的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 520是什么节日 520节日的来源
- 下一篇: Frogs HDU - 5514