Codeforces

来源:互联网 发布:ubuntu mysql启动失败 编辑:程序博客网 时间:2024/06/10 21:19

B. Complete The Graph

题目链接

分类:构造、最短路

1.题意概述

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

2.解题思路

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

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

3.AC代码

#include <bits/stdc++.h>#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<node> 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;}