Codeforces Round #Pi (Div. 2) E. President and Roads 最短路,桥

来源:互联网 发布:vnpy 知乎 编辑:程序博客网 时间:2024/05/22 06:26

题意:有n个城市,一些单向道路,每条道路会花费一些时间。总统从s到t,他会选择最快的道路,有一些道路是一定会选的,有一些道路通过修缮可以降低通过时间(>0),使总统必然走这条路,有些路一定是不通过的。

分析:从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 longusing 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;}


0 0
原创粉丝点击