Codeforces 716D - Complete The Graph(最短路)

题意:给定n个点,m条边,以及起点s,终点t,问你图中是否存在s->t的最短路为L,其中权值为0的可以任意修改。

思路:对给定的边分为2类,权重不为0的直接扔进去建图,权重为0的边先存起来。接着跑一遍堆优化的dij,如果dis[t]小于L,那么无论怎么修改权重0的边都没有办法凑出最短路L;

如果dis[t]=L,那么直接输出;如果dis[t]>L,则将原来事先存起来的边一条一条的加进去,权值设为1。每加一条边就跑一次dij,一旦找到dis[t]<=L,就可以终止并输出。

PS:原来堆优化的dij就是用优先队列优化,自己敲了一遍才知道,看来模板这东西得多敲才会懂。。。

  1 #include <iostream>
  2 #include <queue>
  3 #include <stack>
  4 #include <cstdio>
  5 #include <vector>
  6 #include <map>
  7 #include <set>
  8 #include <bitset>
  9 #include <algorithm>
 10 #include <cmath>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <string>
 14 #include <sstream>
 15 #include <time.h>
 16 #define x first
 17 #define y second
 18 #define pb push_back
 19 #define mp make_pair
 20 #define lson l,m,rt*2
 21 #define rson m+1,r,rt*2+1
 22 #define mt(A,B) memset(A,B,sizeof(A))
 23 #define mod 1000000007
 24 using namespace std;
 25 typedef long long LL;
 26 const double PI = acos(-1);
 27 const int N=30000+10;
 28 const int inf = 0x3f3f3f3f;
 29 //const LL INF=0x3f3f3f3f3f3f3f3fLL;
 30 const LL INF=1e15;
 31 struct node
 32 {
 33     int u,v,next;
 34     LL w;
 35 } E[N];
 36 int n,m,s,t,top=0,head[N];
 37 LL L,dis[N];
 38 bool vis[N];
 39 vector<node> P;
 40 void add(int u,int v,LL w)
 41 {
 42     E[top].u=u;
 43     E[top].v=v;
 44     E[top].w=w;
 45     E[top].next=head[u];
 46     head[u]=top++;
 47 }
 48 struct Node//堆优化的dij所用的结构体
 49 {
 50     int v;//点
 51     LL d;//距离
 52     Node(int v=0,LL d=0):v(v),d(d) {}//我也不懂为什么这样写,反正照写就对了
 53     bool operator <(const Node &r)const
 54     {
 55         return d>r.d;
 56     }
 57 };
 58 void dij()
 59 {
 60     for(int i=0; i<N; i++)//先初始化
 61     {
 62         dis[i]=INF;
 63         vis[i]=false;
 64     }
 65     dis[s]=0;
 66     priority_queue<Node> Q;
 67     Q.push(Node(s,0));
 68     while(!Q.empty())
 69     {
 70         Node p=Q.top();
 71         Q.pop();
 72         if(vis[p.v])continue;
 73         vis[p.v]=true;
 74         for(int i=head[p.v]; i!=-1; i=E[i].next)
 75         {
 76             int v=E[i].v;
 77             if(!vis[v]&&dis[v]>dis[p.v]+E[i].w)//松弛法
 78             {
 79                 dis[v]=dis[p.v]+E[i].w;
 80                 Q.push(Node(v,dis[v]));
 81             }
 82         }
 83     }
 84 }
 85 int main()
 86 {
 87 #ifdef Local
 88     freopen("data.txt","r",stdin);
 89 #endif
 90     int u,v;
 91     LL w;
 92     mt(head,-1);//邻接表初始化
 93     cin>>n>>m>>L>>s>>t;
 94     for(int i=0; i<m; i++)//先将节点分类,w!=0的先加进去建图
 95     {
 96         cin>>u>>v>>w;
 97         if(w)
 98         {
 99             add(u,v,w);
100             add(v,u,w);
101         }
102         else
103         {
104             node p;
105             p.u=u;
106             p.v=v;
107             p.w=w;
108             p.next=-1;
109             P.pb(p);
110         }
111     }
112     dij();
113     if(dis[t]<L)
114     {
115         puts("NO");
116     }
117     else if(dis[t]==L)
118     {
119         puts("YES");
120         for(int i=0; i<top; i+=2)
121         {
122             printf("%d %d %I64d\n",E[i].u,E[i].v,E[i].w);
123         }
124         for(int i=0; i<P.size(); i++)
125         {
126             printf("%d %d %I64d\n",P[i].u,P[i].v,INF);
127         }
128     }
129     else
130     {
131         int pos=0,flag=0;
132         for(pos=0; pos<P.size(); pos++)
133         {
134             add(P[pos].u,P[pos].v,1);
135             add(P[pos].v,P[pos].u,1);
136             dij();
137             if(dis[t]<=L)
138             {
139                 E[top-1].w+=L-dis[t];
140                 E[top-2].w+=L-dis[t];
141                 flag=1;
142                 break;
143             }
144         }
145         if(!flag)puts("NO");
146         else
147         {
148             puts("YES");
149             for(int i=0; i<top; i+=2)
150             {
151                 printf("%d %d %I64d\n",E[i].u,E[i].v,E[i].w);
152             }
153             for(int i=pos+1; i<P.size(); i++)
154             {
155                 printf("%d %d %I64d\n",P[i].u,P[i].v,INF);
156             }
157         }
158     }
159 #ifdef Local
160     cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
161 #endif
162 }

时间: 2025-01-14 08:20:48

Codeforces 716D - Complete The Graph(最短路)的相关文章

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

原文链接https://www.cnblogs.com/zhouzhendong/p/CF715B.html 题解 接下来说的“边”都指代“边权未知的边”. 将所有边都设为 L+1,如果dis(S,T) < L ,那么必然无解. 将所有边都设为 1 ,如果 dis(S,T) > L ,那么必然无解. 考虑将任意一条边的权值+1,则 dis(S,T) 会 +0 或者 +1 . 如果将所有边按照某一个顺序不断+1,直到所有边的权值都是L+1了,那么在这个过程中,dis(S,T) 是递增的,而且一定

CF 505B Mr. Kitayuta&#39;s Colorful Graph(最短路)

题意  求两点之间有多少不同颜色的路径 范围比较小  可以直接floyd #include<cstdio> #include<cstring> using namespace std; const int N = 105; int d[N][N][N], ans; int main() { int a, b, c, n, m, q; while(~scanf("%d%d", &n, &m)) { memset(d, 0, sizeof(d));

Codeforces 459E Pashmak and Graph(dp+贪心)

题目链接:Codeforces 459E Pashmak and Graph 题目大意:给定一张有向图,每条边有它的权值,要求选定一条路线,保证所经过的边权值严格递增,输出最长路径. 解题思路:将边按照权值排序,每次将相同权值的边同时加入,维护每个点作为终止点的最大长度即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 3

codeforces 715B:Complete The Graph

Description ZS the Coder has drawn an undirected graph of n vertices numbered from 0 to n - 1 and m edges between them. Each edge of the graph is weighted, each weight is a positive integer. The next day, ZS the Coder realized that some of the weight

Codeforces Round #372 (Div. 1) B. Complete The Graph

题目链接:传送门 题目大意:给你一副无向图,边有权值,初始权值>=0,若权值==0,则需要把它变为一个正整数(不超过1e18),现在问你有没有一种方法, 使图中的边权值都变为正整数的时候,从 S 到 T 的最短路恰好等于 L. 若没有输出 "NO",否则输出 "YES",同时输出新图中的所有边权值. 题目思路:二分+最短路(spfa or dijkstra) 闲谈:先%一发杜教,思路来源于看他的代码.然后蒟蒻spfa 982ms,杜教 dijkstra 93m

Codeforces 449B Jzzhu and Cities(最短路)

题目链接:Codeforces 449B Jzzhu and Cities 题目大意:Jzzhu是一个国家的总统,这个国家有N座城市,以1为首都,已经存在了M条公路,给定M条路.并且还有K条铁轨,铁轨均有首都出发,连接si,距离为yi.现在Jzzhu想要节省经费,拆除一些铁轨,问说最多能拆除多少个铁轨,要求每座城市与首都的最短距离不变. 解题思路:最短路,多加一个标记数组,每个si标记1,如果这些点的最短距离被更新,则将对应si的标记清为0,最后统计一下剩余的标记,即为不能拆除的铁轨. #inc

CodeForces 709B Checkpoints (数学,最短路)

题意:给定你的坐标,和 n 个点,问你去访问至少n-1个点的最短路是多少. 析:也是一个很简单的题,肯定是访问n-1个啊,那么就考虑从你的位置出发,向左访问和向右访问总共是n-1个,也就是说你必须从1 - n-1 全访问一次, 或者是2 - n 全访问一次,有一段是访问了两次,加上就好. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <s

codeforces 340D Bubble Sort Graph(dp,LIS)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud  Bubble Sort Graph Iahub recently has learned Bubble Sort, an algorithm that is used to sort a permutation with n elements a1, a2, ..., an in ascending order. He is bored of this so simple al

[ An Ac a Day ^_^ ] CodeForces 601A The Two Routes 最短路

14号就ccpc全国赛的全国赛了 而且也快东北赛的选拔赛了 现在队伍实力实在不行 参加了也是边缘化的队伍 虽然有新生保护的设置 但实话说 机会还是不大 所以不如趁现在开始好好努力 明年也许还有机会 An Ac a Day ( of course not keep a girl away ^_^ ) 题意呢 一个人开火车 一个人开大巴 火车走铁路 大巴走公路 现在有n个城镇 每两个城镇之间都有路 其中m条铁路 其他的都是公路 要求两个人都从1开始走 途中不相遇 问最快要多久 题面比较诡异 两个人