zoukankan      html  css  js  c++  java
  • codeforces Gym 100338C Important Roads (重建最短路图)

    正反两次最短路用于判断边是不是最短路上的边,把最短路径上的边取出来建图。然后求割边。注意重边,和卡spfa。

    正权,好好的dijkstra不用,用什么spfa?

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    #define fi first
    #define se second
    #define bug(x) cout<<#x<<'='<<x<<endl;
    #define FOR(i,s,e) for(int i = s; i < e; i++)
    
    const int maxn = 2e4+5;
    const int maxe = 2e5+10;
    ll d1[maxn],d2[maxn];
    struct Graph
    {
        int head[maxn],fro[maxe],to[maxe],nxt[maxe],ecnt;
        ll w[maxe];
        void init() {     memset(head,-1,sizeof(head)); ecnt = 0; }
        Graph(){ init(); }
        void addEdge(int u,int v,ll l)
        {
            fro[ecnt] = u;
            to[ecnt] = v;
            w[ecnt] = l;
            nxt[ecnt] = head[u];
            head[u] = ecnt++;
        }
    }G1,G3;
    int id[maxe];
    
    const ll INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int cut[maxe]; // 0 not shortest path 1 shortest path 2 unique shortest path
    int dfs_clock,dfn[maxn],low[maxn];
    void Tarjan(int u,int fa)
    {
        dfn[u] = low[u] = ++dfs_clock;
        for(int i = G3.head[u]; ~i; i = G3.nxt[i]){
            if((i^1) == fa) continue;
            int v = G3.to[i];
            if(!dfn[v]){
                Tarjan(v,i);
                low[u] = min(low[u],low[v]);
                if(low[v]>dfn[u]) {
                    cut[id[i]] = 1;
                }
            }else { low[u] = min(low[u],low[v]); }
        }
    }
    struct Node
    {
        ll d;
        int u;
        bool operator < (const Node& x) const{
            return d > x.d;
        }
    };
    
    bool vis[maxn];
    void Dijkstra(int s,Graph &g,ll (&d)[maxn])
    {
        memset(vis,0,sizeof(vis));
        priority_queue<Node> q;
        memset(d,0x3f,sizeof(d));
        d[s] = 0;
        q.push(Node{0,s});
        while(q.size()){
            Node x = q.top(); q.pop();
            int u = x.u;
            if(vis[u]) continue;
            vis[u] = true;
            for(int i = g.head[u]; ~i; i = g.nxt[i] ){
                int v = g.to[i];
                if(v == u) continue;
                if(d[v]> d[u]+g.w[i]){
                    d[v] = d[u]+g.w[i];
                    q.push(Node{d[v],v});
                }
            }
        }
    }
    
    
    vector<int> ans;
    bool evis[maxe];
    
    int main()
    {
        freopen("important.in","r",stdin);
        freopen("important.out","w",stdout);
        int n,m,s,t;
        scanf("%d%d",&n,&m);
        s = 1; t = n;
        for(int i = 0; i < m; i++){
            int u,v,l; scanf("%d%d%d",&u,&v,&l);
            G1.addEdge(u,v,l); G1.addEdge(v,u,l);
        }
        Dijkstra(s,G1,d1);
        Dijkstra(t,G1,d2);
        ll shortest = d1[t];
        for(int i = 0,M = m*2; i < M; i++){
            int u = G1.fro[i], v = G1.to[i];
            if(shortest == G1.w[i] + d1[u] + d2[v] ){
                int eid = i/2;
                if(!evis[eid]){
                    evis[eid] = true;
                    id[G3.ecnt] = eid; G3.addEdge(u,v,G1.w[i]);
                    id[G3.ecnt] = eid; G3.addEdge(v,u,G1.w[i]);
                }
            }
        }
        Tarjan(s,-1);
        if(~G3.nxt[G3.head[s]]){
            for(int i = G3.head[s]; ~i; i = G3.nxt[i]){
                cut[id[i]] = 0;
            }
        }
        for(int i = 0; i < m; i ++){
            if(cut[i]) ans.push_back(i+1);
        }
        int sz = ans.size();
        printf("%d
    ",sz--);
        for(int i = 0; i <= sz; i++){
            printf("%d%c",ans[i],i == sz?'
    ':' ');
        }
        return 0;
    }
  • 相关阅读:
    redis 订阅者与发布者(命令行)
    CentOS 6 使用 tptables 打开关闭防火墙与端口
    CentOS 7 使用 firewalld 打开关闭防火墙与端口
    Python面向对象编程-OOP
    python命名规则 PEP8编码规则(约定俗成)
    python 装饰器 概念
    python常用模块 os,datetime,time,MySQLdb,hashlib
    python xml.etree.ElementTree 处理xml 文件 变量 流 xml概念
    Pycharm小技巧
    python概要笔记2
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4748495.html
Copyright © 2011-2022 走看看