zoukankan      html  css  js  c++  java
  • CF716D Complete The Graph

    图论+构造

    首先可以发现如果去除了可以改变权值的边,$s$到$t$的最短路若小于$l$,那么一定不行

    若等于则直接将可改边权的边改为inf,输出即可

    那么现在原图中的最短路是大于$l$的

    因为每一条边是都要加入图中的,而且每条边边权至少为1

    那么可以不断向图中加入权值为1的边,并且在加边的过程中不断跑最短路

    如果加完当前的边,$s$到$t$的最短路小于l的话,将这条边权值增加

    剩下的边边权改为inf即可

    简单证明这种做法

    首先考虑加入1边后,最短路依然大于$l$,那么继续使最短路减小

    再考虑加入1边后,最短路小于$l$

    因为在加入这条边之前最短路大于$l$,那么加入这条边后,最短路肯定经过这条边

    而增加边权之后,最短路还是比之前的小,那么最短依然经过这条边

    不会出现增加了这条边的边权之后,最短路不经过这条边的情况

    那么得到的图最短路必定为$l$

    #include <bits/stdc++.h>
    #define ll long long
    #define inf (ll)1e17;
    using namespace std;
    const int MAXN=20100;
    int n,m,l,s,t,tot;
    int first[1100],nxt[MAXN],point[MAXN];
    int vi[1100];
    ll d[1100],len[MAXN];
    struct node
    {
        int u,v;
        ll l;
    }sh[MAXN];
    void add_edge(int x,int y,int z)
    {
        tot++;
        nxt[tot]=first[x];
        first[x]=tot;
        point[tot]=y;
        len[tot]=z;
    }
    void spfa()//最短路
    {
        queue <int> q;
        for (int i=0;i<n;i++)
          d[i]=inf;
        d[s]=0;
        vi[s]=1;
        q.push(s);
        while (!q.empty())
        {
            int f;
            f=q.front();
            q.pop();
            vi[f]=0;
            for (int i=first[f];i!=-1;i=nxt[i])
            {
                int u;
                u=point[i];
                if (d[u]>d[f]+len[i])
                {
                    d[u]=d[f]+len[i];
                    if (!vi[u])
                    {
                        vi[u]=1;
                        q.push(u);
                    }
                }
            }
        }
    }
    int main()
    {
        tot=-1;
        memset(first,-1,sizeof(first));
        memset(nxt,-1,sizeof(nxt));
        scanf("%d%d%d%d%d",&n,&m,&l,&s,&t);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d%lld",&sh[i].u,&sh[i].v,&sh[i].l);
            if (sh[i].l==0)
              continue;
            add_edge(sh[i].u,sh[i].v,sh[i].l);
            add_edge(sh[i].v,sh[i].u,sh[i].l);
        }
        spfa();
        if (d[t]<l)
        {
            printf("NO
    ");
            return 0;
        }
        if (d[t]==l)//注意
        {
            printf("YES
    ");
            for (int i=1;i<=m;i++)
            {
                if (sh[i].l==0)
                  sh[i].l=inf;
                printf("%d %d %lld
    ",sh[i].u,sh[i].v,sh[i].l);
            }
            return 0;
        }
        int wh;
        for (int i=1;i<=m;i++)
        {
            if (sh[i].l==0)
            {
                add_edge(sh[i].u,sh[i].v,1);
                add_edge(sh[i].v,sh[i].u,1);
                spfa();
                if (d[t]>l)
                {
                    sh[i].l=1;
                    continue;
                }
                sh[i].l=1+l-d[t];
                wh=i;
                break;
            }
        }
        tot=-1;
        memset(first,-1,sizeof(first));
        memset(nxt,-1,sizeof(nxt));
        for (int i=wh+1;i<=m;i++)
        {
            if (sh[i].l==0)
              sh[i].l=inf;
        }
        for (int i=1;i<=m;i++)
        {
            add_edge(sh[i].u,sh[i].v,sh[i].l);
            add_edge(sh[i].v,sh[i].u,sh[i].l);
        }
        spfa();
        if (d[t]!=l)
        {
            printf("NO
    ");
            return 0;
        }
        printf("YES
    ");
        for (int i=1;i<=m;i++)
          printf("%d %d %lld
    ",sh[i].u,sh[i].v,sh[i].l);
    }
  • 相关阅读:
    centos6和centos7升级openssh7.5脚本
    开通telnet服务,使用telnet登入
    彻底删除kafka的topic以及其中的数据
    redis集群创建
    curl 命令参数
    nginx.conf配置文件详解,白嫖的
    logstash迁移es数据
    es 常用查询
    pl/sql 存储过程
    es查看集群信息命令_cat和_cluster
  • 原文地址:https://www.cnblogs.com/huangchenyan/p/11316995.html
Copyright © 2011-2022 走看看