您的位置:首页 > 其它

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

2015-08-12 11:08 351 查看
题意:有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 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: