标签:
对于 20%的数据,满足 N≤15,M≤50;
对于 50%的数据,满足 N≤500,M≤6,000;
对于 100%的数据,满足 N≤3,000,M≤70,000,1≤wi≤108
。
输入数据保证一定有解,且不会存在维持某个城市结界的结界发生器在这个
城市内部。
连接两个城市的道路可能不止一条, 也可能存在一个城市自己到自己的道路。
【思路】
Dijkstra
用d1[],d2[]分别表示到达该点的时间和将连接保护器全部毁掉的时间,则到达该点的实际时间为max{ d1[i],d2[i] }。使用dijkstra算法,每次更新连接节点的d1和所保护节点的d2,当一个节点不再受到保护时入队。
【代码】
1 #include<cmath> 2 #include<queue> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 #define pa pair<int,int> 9 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 10 using namespace std; 11 12 const int N = 3000+10; 13 struct Edge{ int v,w; }; 14 15 void read(int& x) { 16 char c=getchar(); int f=1; x=0; 17 while(!isdigit(c)) {if(c==‘-‘)f=-1; c=getchar();} 18 while(isdigit(c)) x=x*10+c-‘0‘,c=getchar(); 19 x*=f; 20 } 21 22 int n,m,d1[N],d2[N],in[N],vis[N]; 23 vector<Edge> g[N]; 24 vector<int> plin[N]; 25 priority_queue<pa,vector<pa>,greater<pa> > q; 26 //重载运算符 27 28 int dijkstra() { 29 FOR(i,1,n) d1[i]=1e9; 30 d1[1]=0; q.push(make_pair(0,1)); 31 while(!q.empty()) { 32 int u=q.top().second; q.pop(); 33 if(vis[u]) continue; 34 vis[u]=1; int mx=max(d1[u],d2[u]); 35 for(int i=0;i<g[u].size();i++) { 36 int v=g[u][i].v; 37 if(d1[v]>mx+g[u][i].w) { 38 d1[v]=mx+g[u][i].w; 39 if(!in[v]) q.push(make_pair(max(d1[v],d2[v]),v)); 40 } 41 } 42 for(int i=0;i<plin[u].size();i++) { 43 int v=plin[u][i]; 44 d2[v]=max(d2[v],mx); 45 if(!(--in[v])) q.push(make_pair(max(d1[v],d2[v]),v)); 46 } 47 } 48 return max(d1[n],d2[n]); 49 } 50 51 int main() { 52 read(n),read(m); 53 int u,v,w; 54 FOR(i,1,m) { 55 read(u),read(v),read(w); 56 if(u!=v) g[u].push_back((Edge){v,w}); 57 } 58 FOR(i,1,n) { 59 read(in[i]); 60 FOR(j,1,in[i]) { 61 read(v); 62 plin[v].push_back(i); 63 } 64 } 65 printf("%d",dijkstra()); 66 return 0; 67 }
bzoj 1922 [Sdoi2010]大陆争霸(最短路变形)
标签:
原文地址:http://www.cnblogs.com/lidaxin/p/5222313.html