Codeforces Round #Pi (Div. 2) E. President and Roads 最短路,桥
2015-08-12 11:08
351 查看
题意:有n个城市,一些单向道路,每条道路会花费一些时间。总统从s到t,他会选择最快的道路,有一些道路是一定会选的,有一些道路通过修缮可以降低通过时间(>0),使总统必然走这条路,有些路一定是不通过的。
分析:从s到t和从t到s分别跑出最短路,对最短路的边新建图,图中的桥即为必然要走的。
分析:从s到t和从t到s分别跑出最短路,对最短路的边新建图,图中的桥即为必然要走的。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstring> #include<cstdio> #include<ostream> #include<istream> #include<algorithm> #include<queue> #include<string> #include<cmath> #include<set> #include<map> #include<stack> #include<vector> #define fi first #define se second #define pii pair<ll,int> #define inf (1ll<<60) #define eps 1e-8 #define ll long long using namespace std; const int maxn=110005; int n,m,s,t; struct Edge { int from,to; int w; int next; }E1[maxn],E2[maxn]; int e1,e2; int h1[maxn],h2[maxn]; ll ds[maxn]; ll dt[maxn]; int ans[maxn]; int cost[maxn]; Edge E3[maxn*2]; int h3[maxn]; int e3; int dfs_clock; int dfn[maxn]; int low[maxn]; bool vis[maxn*2]; void addEdge(int from,int to,int w,int* h,Edge* e,int& ne) { e[ne].from=from; e[ne].to=to; e[ne].w=w; e[ne].next=h[from]; h[from]=ne++; } void Dij(int s,ll* d,Edge* e,int* head) { for(int i=1;i<=n;i++) d[i]=inf; d[s]=0; priority_queue<pii,vector<pii>,greater<pii> >que; que.push(pii(0,s)); while(!que.empty()) { pii u=que.top(); que.pop(); if(u.fi>d[u.se]) continue; for(int i=head[u.se];i!=-1;i=e[i].next) { int v=e[i].to; if(d[v]>u.fi+e[i].w) { d[v]=u.fi+e[i].w; que.push(pii(d[v],v)); } } } } void add(int from,int to,int id) { E3[e3].from=from; E3[e3].to=to; E3[e3].w=id; E3[e3].next=h3[from]; h3[from]=e3++; E3[e3].from=to; E3[e3].to=from; E3[e3].w=id; E3[e3].next=h3[to]; h3[to]=e3++; } void buildGraph() { e3=0; memset(h3,-1,sizeof(h3)); for(int i=0;i<e1;i++) { if(ds[E1[i].from]+E1[i].w+dt[E1[i].to]==ds[t]) { add(E1[i].from,E1[i].to,i); } } } void dfs(int u) { dfn[u]=low[u]=++dfs_clock; for(int i=h3[u];i!=-1;i=E3[i].next) { int v=E3[i].to; if(!dfn[v]) { vis[i]=vis[i^1]=true; //消除重边的影响 dfs(v); low[u]=min(low[v],low[u]); if(low[v]>dfn[u]) { ans[E3[i].w]=1; } } else if(dfn[v]<dfn[u] && !vis[i]) { vis[i]=vis[i^1]=1; low[u]=min(low[u],dfn[v]); } } } void findBridge() { dfs_clock=0; memset(dfn,0,sizeof(dfn)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { if(!dfn[i]) dfs(i); } } int main() { int a,b,l; scanf("%d%d%d%d",&n,&m,&s,&t); memset(h1,-1,sizeof(h1)); memset(h2,-1,sizeof(h2)); e1=e2=0; for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&l); addEdge(a,b,l,h1,E1,e1); addEdge(b,a,l,h2,E2,e2); } Dij(s,ds,E1,h1); Dij(t,dt,E2,h2); memset(ans,-1,sizeof(ans)); buildGraph(); findBridge(); for(int i=0;i<e1;i++) { if(ans[i]==-1) { ll p=ds[t]-1-ds[E1[i].from]-dt[E1[i].to]; if(p>0) { ans[i]=0; cost[i]=E1[i].w-p; } } } for(int i=0;i<e1;i++) { if(ans[i]==1) printf("YES\n"); else if(ans[i]==0) { printf("CAN %d\n",cost[i]); } else printf("NO\n"); } return 0; }
相关文章推荐
- X210烧写linux系统
- MFC判断某路径下的目标文件是否存在
- 用CSS和SVG制作饼图
- LeetCode题解:Contains Duplicate
- iOS中的NSString
- 在linux jexus下新建站点
- c# 关于HtmlGenericControl 类的笔记(自用)
- 如何收集 NGINX 指标(第二篇)
- curl_init不支持,该如何开启
- 备份
- poj3258 二分最小值最大化
- 16进制颜色代码记忆规律/
- Java基础学习总结—Java对象的序列化和反序列化
- HDU5373——同余模——The shortest problem
- 在DOS命令行窗口中显示系统环境环境变量
- [css3]圆盘旋转动画
- iOS中的NSdate
- TCP长连接与短连接的区别
- Valid Parentheses
- Linux命令详解 -- iptables