【题目链接】:http://codeforces.com/problemset/problem/716/D

【题意】



给你一张图;

这张图上有一些边的权值未知;

让你确定这些权值(改成一个正整数)

使得s到t的最短路恰好为L

【题解】



首先;

算出两个值

temp1->所有的未知边的权值都为1->算出s到t的最短路;

temp2->所有的未知边的权值都为INF->算出s到t的最短路;

则必须要有

temp1<=L<=temp2

否则无解;

明白这个之后;

为每一个未知的边都标号;

标号为1..totl;

然后;

二分有多少条未知边的权值边为1;

->mid

找到最小的,使得在mid条未知边的权值为1的时候;

s到t的最短路小于L;

则第mid条边必然在s->t的最短路上;

则把那第mid条边再加上s->t的最短路与L的差值

(前Mid-1条边权值还是1);

(因为1的边越多,s到t的最短路是单调不上升的,所以这么做是可行的)

(又因为是>L和< L的边界,所以那个mid一定是在最短路上的,且没有它最短路就会大于L)



【Number Of WA】



1



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1100;
const int M = 20000+100;
const int INF = 1e9+1; int fir[N],nex[M],en[M],w[M],lable[M];
int totm,totl,n,m,L,s,t;
LL dis[N];
bool exsit[N];
queue <int> dl; void add(int x,int y,int z,int flag)
{
nex[totm] = fir[x];
fir[x] = totm;
en[totm] = y;
w[totm] = z;
if (flag) lable[totm] = totl;
totm++;
} LL spfa(int pre)
{
rep1(i,1,n) dis[i] = -1;
exsit[s] = true;
dl.push(s);
dis[s] = 0;
while (!dl.empty())
{
int x = dl.front();
dl.pop();
exsit[x] = false;
for (int i = fir[x];i>=0;i = nex[i])
{
int y = en[i],cost = w[i];
if (lable[i] && lable[i]<=pre) cost = 1;
if (lable[i] && lable[i]>pre) cost = INF;
if (dis[y]==-1 || dis[y]>dis[x]+cost)
{
dis[y] = dis[x]+cost;
if (!exsit[y])
{
exsit[y] = true;
dl.push(y);
}
}
}
}
return dis[t];
} void out_graph(int key,int sp )
{
rep1(i,1,n)
{
for (int j = fir[i];j >= 0;j = nex[j])
{
if (j&1) continue;
cout <<i-1<<' '<<en[j]-1<<' ';
int cost = w[j];
if (lable[j])
{
if (lable[j]<key) cost = 1;
if (lable[j]==key) cost = sp;
if (lable[j]>key) cost = INF;
}
cout << cost << endl;
}
}
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
ios::sync_with_stdio(false),cin.tie(0);//scanf,puts,printf not use
cin >> n >> m >> L >> s >> t;s++,t++;
rep1(i,1,n) fir[i] = -1;
rep1(i,1,m)
{
int x,y,z;
cin >> x >> y >> z;
x++,y++;
if (z==0) totl++;
add(x,y,z,z==0);
add(y,x,z,z==0);
}
LL temp1 = spfa(totl),temp2 = spfa(0);
if (temp1 <= L && L <= temp2)
{
cout << "YES" << endl;
int l = 0,r = totl,ans;
LL tl,ansl;
while (l <= r)
{
int mid = (l+r)>>1;
tl = spfa(mid);
if (tl<=L)
ans = mid,r = mid-1,ansl = tl;
else
l = mid+1;
}
out_graph(ans,L-ansl+1);
}
else
cout << "NO" << endl;
return 0;
}

最新文章

  1. ADO.net 更新和插入数据 遇到null 执行不成功
  2. VS2012配置OpenCV、GDAL开发环境
  3. Samba 4.x.x全版本存在命令执行漏洞
  4. window.history
  5. C#类索引器的使用
  6. Memcached Java Client with sample program--reference
  7. 《你不知道的JavaScript》整理(六)——强制类型转换
  8. 再起航,我的学习笔记之JavaScript设计模式17(模板方法模式)
  9. 17-TypeScript代理模式
  10. UVA11404:Palindromic Subsequence
  11. IDEA+MySQL实现登录注册的注册验证时出现 Cannot resolve query parameter &#39;2&#39;
  12. bzoj1026
  13. OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法
  14. js 获取数组重复的元素
  15. Pytorch中的Batch Normalization操作
  16. 在sorted range上的操作(includes,set_union,set_intersection,set_difference)
  17. Git初级使用教程
  18. Java 常用对象-Object类
  19. c++ vector, 迭代器
  20. Redis高可用及分片集群

热门文章

  1. 2015年北京大学软件project学科优秀大学生夏令营上机考试---C:单词翻转面试题
  2. PowerDesigner里面将表中name列值拷贝到comment列
  3. contest hunter 6803 导弹防御塔
  4. Jungle Roads --hdoj
  5. Hdu-6253 2017CCPC-Final K.Knightmare 规律
  6. Visual Studio写Cuda代码
  7. linux 添加 msyql 开机自启动
  8. 机器学习——SVM讲解
  9. element-ui 分页中的slot的用法(自定义分页显示内容)
  10. testNG中方法的调用顺序