• 【NOIP模拟】军队调遣


    题面

    OI 国有 N 座城市,每座城市有唯一的 1 到 N 的标号。其中 1 号城市为首都。 OI 国的交通 十分发达,共有 M 条有向道路,已知通过第 i 条道路所需时间为 ti。  林大帝的统治使 OI 国走向了繁荣。  不幸的是,各地都仍旧有一些不老实的人在捣蛋。林大帝实在是不能忍了。为了加强治安, 保障国土的完整,林大帝派人在每座城市(除了首都本身)招募军队去剿匪。匪徒都是些乌合 之众,没过一会儿就被林大帝的精锐之师打得落花流水、心服口服。  为了庆祝剿匪胜利,各地的军队都必须尽快到首都集合。然而,行军是会产生劳累值的,且 军队在剿匪之后十分疲惫,所以他们会优先选择劳累值最小的路径。如果有多个劳累值最小的 路径,他们会在其中选择用时最少的路径。  当军队经过一条 u 到 v 的道路时,如果 v 能够到达 u,士兵们就会有绕圈的感觉,故产生 1 单位的劳累值;否则,士兵们会有说有笑地前进,不会产生劳累值。一条路径的劳累值为路径 上所有边的劳累值之和,一条路径的用时为路径上所有边的用时之和,如有边重复经过需累计。 你需要对每座城市计算其军队将选择的路径的劳累值及用时,或指出无法到达首都。

    输出共 N − 1 行,第 i 行描述 i + 1 号城市的军队选择的路径情况。如果该城市的军队不能 到达首都,输出 -1;否则输出两个整数依次表示劳累值和用时。

    分析

    通过计算用时可以感知出是一个最短路问题,但是多了劳累值的问题,稍微复杂一点

    但是要使u能到v并且v能到u,对于有向图来说,很明显是在一个环里,所以我们只需要将强连通分量染色,再给边标上第二层边权,如果两节点为同一个强连通分量里,则边权标为1,否则标为0。

    之后通过最短路算法,同时计算时间和劳累值的最小,但是按照劳累值优先。

    注意建图需要反向建!

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100100
    #define INF 0X7fffffff7fffffff
    #define ll long long
    ll low[N],dfn[N],first[N],head[N],vis[N],col[N],v[N],u[N],w[N],t[N],d[N];
    ll n,m,dep,cnt,gro,cot;
    struct email
    {
        ll u,v,w;
        ll nxt;
    }e[N*4],g[N*4];
    queue<ll>q;
    stack<ll>s;
    inline void add(ll u,ll v,ll w)
    {
        e[++cnt].nxt=first[u];first[u]=cnt;
        e[cnt].u=u;e[cnt].v=v;e[cnt].w=w;
    }
    
    inline void readd(ll u,ll v,ll w)
    {
        g[++cot].nxt=head[u];head[u]=cot;
        g[cot].u=u;g[cot].v=v;g[cot].w=w;
    }
    
    void spfa(ll x)
    {
        q.push(x);vis[x]=1;t[x]=0;d[x]=0;
        while(!q.empty())
        {
            ll u=q.front();q.pop();vis[u]=0;
            for(ll i=head[u];i;i=g[i].nxt)
            {
                ll v=g[i].v,tim=g[i].w,w=e[i].w;
                if(t[v]>t[u]+tim)
                {
                    t[v]=t[u]+tim;
                    d[v]=d[u]+w;
                    if(!vis[v])
                    {
                        q.push(v);
                        vis[v]=1;
                    }
                }
                if(t[v]==t[u]+tim)
                    if(d[v]>d[u]+w)
                    {
                        d[v]=d[u]+w;
                        if(!vis[v])
                        {
                            q.push(v);
                            vis[v]=1;
                        }
                        
                    }    
            }
        }
    }
    
    void tarjan(ll u)
    {
        low[u]=dfn[u]=++dep;
        s.push(u);vis[u]=1;
        for(ll i=first[u];i;i=e[i].nxt)
        {
            ll v=e[i].v;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else
                if(vis[v])
                    low[u]=min(low[u],dfn[v]);    
        }
        if(dfn[u]==low[u])
        {
            gro++;
            while(1)
            {
                ll tt=s.top();s.pop();
                col[tt]=gro;
                vis[tt]=0;
                if(tt==u)break;
            }
        }
    }
    
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=m;i++)
        {
            scanf("%lld%lld%lld",&u[i],&v[i],&w[i]);
            add(v[i],u[i],w[i]);
        }
        tarjan(1);
        for(ll i=1;i<=m;i++)
        {
            ll u1=u[i],v1=v[i],w1;
            if(col[u1]==col[v1])
                w1=1;
            else
                w1=0;
            readd(v1,u1,w1);
        }
    
        memset(vis,0,sizeof(vis));
        for(ll i=1;i<=n;i++)
            t[i]=INF,d[i]=INF;
        spfa(1);
        for(ll i=2;i<=n;i++)
        {
            if(t[i]==INF||d[i]==INF)
                printf("-1
    ");
            else
                printf("%lld %lld
    ",t[i],d[i]);
        }
        
    }
    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    Oracle SQL语句收集
    SqlParameter In 查询
    SQL 性能优化
    Entity Framework
    【XLL API 函数】 xlfSetName
    【XLL API 函数】xlfUnregister (Form 2)
    【XLL API 函数】xlfUnregister (Form 1)
    【Excel 4.0 函数】REGISTER 的两种形式以及VBA等效语句
    【Excel 4.0 函数】REGISTER
    【Bochs 官方手册翻译】 第一章 Bochs介绍
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9483477.html
Copyright © 2020-2023  润新知