zoukankan      html  css  js  c++  java
  • The Shortest Statement CodeForces

    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #include <map>
    #include <set>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #define rap(i, a, n) for(int i=a; i<=n; i++)
    #define MOD 2018
    #define LL long long
    #define ULL unsigned long long
    #define Pair pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define _  ios_base::sync_with_stdio(0),cin.tie(0)
    //freopen("1.txt", "r", stdin);
    using namespace std;
    const int maxn = 2 * 1e5 + 10, INF = 0x7fffffff;
    LL n, m, cnt1, cnt2, c;
    LL head1[maxn], head2[maxn], f[maxn], vis[maxn], bz[maxn];
    LL dis[50][maxn], d[maxn];
    LL res[maxn];
    vector<LL> se;
    struct node
    {
        LL u, v, w, next;
    }Node[maxn];
    
    struct edge
    {
        LL u, v, id, next;
    }Edge[maxn];
    
    void add1_(LL u, LL v, LL w)
    {
        Node[cnt1].u = u;
        Node[cnt1].v = v;
        Node[cnt1].w = w;
        Node[cnt1].next = head1[u];
        head1[u] = cnt1++;
    }
    
    void add1(LL u, LL v, LL w)
    {
        add1_(u, v, w);
        add1_(v, u, w);
    }
    
    void add2_(LL u, LL v, LL id)
    {
        Edge[cnt2].u = u;
        Edge[cnt2].v = v;
        Edge[cnt2].id = id;
        Edge[cnt2].next = head2[u];
        head2[u] = cnt2++;
    }
    
    void add2(LL u, LL v, LL id)
    {
        add2_(u, v, id);
        add2_(v, u, id);
    }
    
    LL find(LL x)
    {
        return f[x]==x?x:(f[x] = find(f[x]));
    }
    
    LL lca(LL u, LL deep, LL root)
    {
        f[u] = u;
        d[u] = deep;
        vis[u] = root;  // 标记属于的树
        for(LL i=head1[u]; i!=-1; i=Node[i].next)
        {
            node e = Node[i];
            if(vis[e.v] == -1)
            {
                bz[i/2] = 1;
                lca(e.v, deep+e.w, root);
                f[e.v] = u;
            }
        }
        for(LL i=head2[u]; i!=-1; i=Edge[i].next)
        {
            edge e = Edge[i];
            if(vis[e.v] == root)   //判断另一个结点是不是和u属于一个树
            {
                LL k = find(e.v);  //寻找最近公共祖先
                res[e.id] = d[u] + d[e.v] - 2*d[k];
            }
        }
    }
    
    void spfa(LL s, LL id)
    {
        for(LL i=0; i<=n; i++) dis[id][i] = INF;
        mem(vis, 0);
        queue<LL> Q;
        Q.push(s);
        vis[s] = 1;
        dis[id][s] = 0;
        while(!Q.empty())
        {
            LL u = Q.front(); Q.pop();
            vis[u] = 0;
            for(LL i=head1[u]; i!=-1; i=Node[i].next)
            {
                node e = Node[i];
                if(dis[id][e.v] > dis[id][u] + e.w)
                {
                    dis[id][e.v] = dis[id][u] + e.w;
                    if(!vis[e.v])
                    {
                        Q.push(e.v);
                        vis[e.v] = 1;
                    }
                }
            }
        }
    }
    
    void init()
    {
        mem(head1, -1);
        mem(head2, -1);
        mem(res, -1);
        mem(vis, -1);
        cnt1 = cnt2 = 0;
    }
    
    int main()
    {
        cin >> n >> m;
        init();
        rap(i, 1, m)
        {
            LL u, v, w;
            scanf("%lld%lld%lld", &u, &v, &w);
            add1(u, v, w);
        }
        cin >> c;
        for(LL i=1; i<=c; i++)
        {
            LL u, v;
            scanf("%lld%lld", &u, &v);
            add2(u, v, i);
        }
        for(LL i=1; i<=n; i++)
            if(vis[i] == -1)
                lca(i, 0, i);
        mem(vis, -1);
        for(LL i=0; i<cnt1; i++)
        {
            if(!bz[i/2])
            {
                if(vis[Node[i].u] == -1) se.push_back(Node[i].u), vis[Node[i].u] = 1;
                if(vis[Node[i].v] == -1) se.push_back(Node[i].v), vis[Node[i].v] = 1;
            }
        }
        for(LL i=0; i<se.size(); i++)
        {
          //  cout << se[i] << endl;
            spfa(se[i], i);
    
        }
    
        for(LL i=1; i<=c; i++)
        {
            for(LL j=0; j<se.size(); j++)
                res[i] = min(res[i], dis[j][Edge[i*2-1].u] + dis[j][Edge[i*2-1].v]);
            printf("%lld
    ", res[i]);
        }
    
    
        return 0;
    }

    The Shortest Statement

     CodeForces - 1051F

    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    利用socket.io实现多人聊天室(基于Nodejs)
    【翻译】Ext JS 5的平板支持
    Spring IoC、DI入门小程序
    初学hibernate之缓存
    获取谷歌浏览器缓存视频方法
    JavaScript模块化学习基础
    HTTP Content-type
    初学Hibernate持久化
    初学Hibernate主键生成策略
    初学Hibernate之Query扩展
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9689559.html
Copyright © 2011-2022 走看看