Codeforces - 715B. Complete The Graph - 构造最短路

B. Complete The Graph

题目链接

分类:构造、最短路

1.题意概述

  • 给你由 n 个点 m 条边构成的图,有些边权是0,现在要你把所有的0改成正整数,问你是否存在一种改法使得由 s t 的最短路是 L

2.解题思路

  • 我们先把那些边权是0的边去掉,跑一遍spfa,如果这样条件下的最短路都小于 L 那肯定是无解!

    如果上述没出现说明可能有解,然后再利用spfa的贪心性质,先给那些边权为0的点先分配权值为1,每一次边权都贪心地改成 ldis(ui,ed) ,加完以后再跑一遍最短路,如果还是大于 L 则肯定无解了。

3.AC代码

#include 
#define INF 1LL << 60
#define maxn 10010
#define N 1111
#define eps 1e-6
#define pi acos(-1.0)
#define e exp(1.0)
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
typedef unsigned long long ull;
struct node
{
    int to, id, flag;
    ll val;
    node(int a, ll b, int c, int d) { to = a; val = b; flag = c; id = d; }
};
struct edge
{
    int u, v, flag;
    ll w;
} E[maxn];
vector mp[N];
ll dis[N], dist[N];
bool vis[N];
bool flag;
void spfa(int sta, int ed, int n, int l, ll dis[])
{
    memset(vis, 0, sizeof(vis));
    fill(dis, dis + n + 1, INF);
    deque<int> q;
    vis[sta] = 1;
    dis[sta] = 0;
    q.push_back(sta);
    while (!q.empty())
    {
        int u = q.front();
        q.pop_front();
        vis[u] = 0;
        int sz = mp[u].size();
        for (int i = 0; i < sz; i++)
        {
            int v = mp[u][i].to;
            ll w = E[mp[u][i].id].w;
            int edge_flag = mp[u][i].flag;
            if (flag)
            {
                if (w != INF && dis[v] > dis[u] + w)
                {
                    dis[v] = dis[u] + w;
                    if (!vis[v])
                    {
                        vis[v] = 1;
                        if (!q.empty() && dis[v] <= dis[q.front()])
                            q.push_front(v);
                        else
                            q.push_back(v);
                    }
                }
            }
            else
            {
                if (edge_flag)
                {
                    ll need = l - dist[ed];
                    if (dist[v] + need > dis[u] + w)
                        w = E[mp[u][i].id].w = mp[u][i].val = dist[v] + need - dis[u];
                }
                if (w != INF && dis[v] > dis[u] + w)
                {
                    dis[v] = dis[u] + w;
                    if (!vis[v])
                    {
                        vis[v] = 1;
                        if (!q.empty() && dis[v] <= dis[q.front()])
                            q.push_front(v);
                        else
                            q.push_back(v);
                    }
                }
            }
        }
    }
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    long _begin_time = clock();
#endif
    int n, m, l, s, t;
    while (~scanf("%d%d%d%d%d", &n, &m, &l, &s, &t))
    {
        for (int i = 0; i <= n; i++)
            mp[i].clear();
        flag = 1;
        for (int i = 0; i < m; i++)
        {
            scanf("%d%d%lld", &E[i].u, &E[i].v, &E[i].w);
            if (!E[i].w)
            {
                E[i].w = 1;
                E[i].flag = 1;
            }
            mp[E[i].u].push_back(node(E[i].v, E[i].w, E[i].flag, i));
            mp[E[i].v].push_back(node(E[i].u, E[i].w, E[i].flag, i));
        }
        spfa(s, t, n, l, dist);
        if (dist[t] > l)
        {
            puts("NO");
            continue;
        }
        flag = 0;
        spfa(s, t, n, l, dis);
        if (dis[t] == l)
        {
            puts("YES");
            for (int i = 0; i < m; i++)
                printf("%d %d %lld\n", E[i].u, E[i].v, E[i].w);
        }
        else
            puts("NO");
    }
#ifndef ONLINE_JUDGE
    long _end_time = clock();
    printf("time = %ld ms.", _end_time - _begin_time);
#endif
    return 0;
}

你可能感兴趣的:(最短路及其变形,构造,Codeforces)