题目描述:

  给定一个 n个点m 条边的带权无向连通图 ,以及一个大小为k 的关键点集合S 。有个人要从点s走到点t,现在可以对所有边加上一个非负整数a,问最大的a,使得加上a后,满足:s到t的最短路长度=s到t且只能经过S中的点的最短路长度。

题目分析:

  暴力

  记x为只经过关键点的最短路长度,其路径条数为n

  记y为可经过任意点的最短路长度,其路径条数为m

   tip:路径条数意思这里指 覆盖最短路的边数

  显然全部加上a之后最短路是不变的

  也就是说我们要求这个东西

$$a*n+x=a*m+y$$

$$a=(\frac{y-x}{n-m})_{max}$$

  所以我们怎么求这个东西呢

  当然是D(bao)P(li)咯

  假设f[i,j],g[i,j]表示到达i这个点,走过了j条边的最短路径

  其中f[i,j]只经过关键点,g[i,j]经过任意一点,这两个数组暴力DP就能求出来

  然后取出最大的a就好了

  关于无解的情况:上面那个式子的值<0显然是不行的,m=n显然是取任意的(当然实现的话就不用这样了判断,这样讲只是方便理解)

  代码:

  

 //许多大佬貌似喜欢在代码上面写自己id,那我这个蒟蒻也就从此开始——跟啦!
//好吧Koko不是重点
//LevenKoko
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define int long long
const int inf=1e18;
using namespace std;
inline int read(){
int ans=,f=;char chr=getchar();
while(!isdigit(chr)){if(chr=='-')f=-;chr=getchar();}
while(isdigit(chr)) {ans=(ans<<)+(ans<<)+chr-;chr=getchar();}
return ans*f;
}const int M=1e4+,N=1e3+;
int n,m,s,t,ans;
int head[N],nxt[M<<],ver[M<<],val[M<<],tot,f[N][N],g[N][N],a[M],k;
inline void add(int x,int y,int z){ver[++tot]=y,nxt[tot]=head[x],val[tot]=z,head[x]=tot;}
inline void Clear_All(){
memset(head,,sizeof(head));
memset(a,,sizeof(a));
for(int i=;i<=n;i++)for(int j=;j<=n;j++)f[i][j]=g[i][j]=inf;
tot=f[s][]=g[s][]=;ans=-;
}
inline void cmin(int &x,int y){return (void)(x=(x>y)?y:x);}
inline void cmax(int &x,int y){return (void)(x=(x>y)?x:y);}
inline void DP1(){
for(int i=;i<n;i++)
for(int j=;j<=n;j++)
if(f[j][i]<inf&&a[j])
for(int k=head[j];k;k=nxt[k])
cmin(f[ver[k]][i+],f[j][i]+val[k]);
}
inline void DP2(){
for(int i=;i<n;i++)
for(int j=;j<=n;j++)
if(g[j][i]<inf)
for(int k=head[j];k;k=nxt[k])
cmin(g[ver[k]][i+],g[j][i]+val[k]);
}
inline void Check_Get(){
for(int i=;i<=n;i++){
if(f[t][i]==inf) continue;
int j;
for(j=;j<=i;j++)
if(g[t][j]<f[t][i]) break;
if(j<=i) continue;
for(j=;j<i;j++) if(g[t][j]!=inf) break;
if(j>=i){
ans=inf; break;
}
int cur=inf;
for(j=;j<i;j++)
cur=min(cur,(-f[t][i]+g[t][j])/(i-j));
for(j=i+;j<=n;j++)
if(f[t][i]+i*cur>g[t][j]+j*cur) break;
if(j<=n) continue;
ans=max(ans,cur);
}
}
signed main(){
// freopen("ernd.in","r",stdin);
// freopen("ernd.out","w",stdout);
int T=read();
while(T--){
n=read(),m=read(),s=read(),t=read();Clear_All();
for(int i=,x,y,z;i<=m;i++)x=read(),y=read(),z=read(),add(x,y,z),add(y,x,z);
k=read();
for(int i=,x;i<=k;i++) x=read(),a[x]=;
DP1();DP2();
Check_Get();
if(ans==-){puts("Impossible");continue;}
if(ans==inf){puts("Infinity");continue;}
printf("%lld\n",ans);
}
return ;
}

LOJ#6075. 「2017 山东一轮集训 Day6」重建的更多相关文章

  1. LOJ #6074. 「2017 山东一轮集训 Day6」子序列

    #6074. 「2017 山东一轮集训 Day6」子序列 链接 分析: 首先设f[i][j]为到第i个点,结尾字符是j的方案数,这个j一定是从i往前走,第一个出现的j,因为这个j可以代替掉前面所有j. ...

  2. loj#6074. 「2017 山东一轮集训 Day6」子序列(矩阵乘法 dp)

    题意 题目链接 Sol 设\(f[i][j]\)表示前\(i\)个位置中,以\(j\)为结尾的方案数. 转移的时候判断一下\(j\)是否和当前位置相同 然后发现可以用矩阵优化,可以分别求出前缀积和逆矩 ...

  3. loj#6076「2017 山东一轮集训 Day6」三元组 莫比乌斯反演 + 三元环计数

    题目大意: 给定\(a, b, c\),求\(\sum \limits_{i = 1}^a \sum \limits_{j = 1}^b \sum \limits_{k = 1}^c [(i, j) ...

  4. Loj #6069. 「2017 山东一轮集训 Day4」塔

    Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...

  5. Loj #6073.「2017 山东一轮集训 Day5」距离

    Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...

  6. Loj 6068. 「2017 山东一轮集训 Day4」棋盘

    Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...

  7. loj #6077. 「2017 山东一轮集训 Day7」逆序对

    #6077. 「2017 山东一轮集训 Day7」逆序对   题目描述 给定 n,k n, kn,k,请求出长度为 n nn 的逆序对数恰好为 k kk 的排列的个数.答案对 109+7 10 ^ 9 ...

  8. LOJ #6119. 「2017 山东二轮集训 Day7」国王

    Description 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当 ...

  9. loj#6073. 「2017 山东一轮集训 Day5」距离(树链剖分 主席树)

    题意 题目链接 Sol 首先对询问差分一下,我们就只需要统计\(u, v, lca(u, v), fa[lca(u, v)]\)到根的路径的贡献. 再把每个点与\(k\)的lca的距离差分一下,则只需 ...

随机推荐

  1. NX二次开发-NXOpen读取工程图注释note1->GetText();

    NX9+VS2012 #include <uf.h> #include <uf_drf.h> #include <NXOpen/Annotations_Note.hxx& ...

  2. iOS7 AVAudioRecorder不能录音

    今天写录音代码的时候,在iOS7以下就可以录音,但是iOS7上不可以,后来才知道iOS7录音方式变了,加上下面的代码就可以了,bingo AVAudioSession *audioSession = ...

  3. var 更明确地表示一个变量被设置为零值

    创建一个变量并被初始化其为零值,习惯使用关键字var.这种做法是为了更明确地表示一个变量被设置为零值. 如果变量被初始化为某个非零值,就配合结构字面量和短变量操作符来创建变量. 零值 数值类型:0 字 ...

  4. 20140307 引用赋值、类的初始化、指针数组、数组指针、new

    引用不能被赋值http://blog.csdn.net/laixingjun/article/details/9005200 类构造函数两种初始化方法区别,哪种好:http://blog.163.co ...

  5. 面向XX程序设计到底是个啥

    面向过程编程:面向(对着)-->过程(流程步骤)-->编程(码代码) IPO是啥 input(输入)-->process(过程处理)-->output(输出) 未来码代码的目的 ...

  6. log4j.rootLogger

    log4j.rootLogger=INFO, FILE, CONSOLE log4j.rootLogger=TRACE, FILE, CONSOLE

  7. SQL语句:一张表和另一张表的多重匹配查询

    1.两个表结构如下图 2.如何查询成如下图所示 3.SQL语句是: select id,name=stuff(( select ','+t2.name from a t1 join b t2 on c ...

  8. 深度探索C++对象模型之第二章:构造函数语意学之成员初始值列表

    当我们需要设置class member的初值时,要么是经过member initialization list ,要么在construcotr内. 一.先讨论必须使用member initializa ...

  9. vue SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

    在使用vue_cli时出现如下错误: 原因是  node  版本太低 应该升级

  10. 廖雪峰Java16函数式编程-2Stream-1Stream简介

    1. Stream Java8引入全新的Stream API 位于java.util.stream包 1.1 Stream API不同于java.io的InputStream/OutputStream ...