建出最短路图之后\(topsort\)即可。

具体思路:

先用\(dijkstra\)算法在原图中跑出\(1\)号点到\(i\)号节点的最短距离\(dist_1(i)\),将所有边反向后用\(dijkstra\)算法求出\(i\)号点到\(2\)号点的最短距离\(dist_2(i)\);

再沿着最短路径找到从\(1\)号点到\(i\)号点的方案数\(f(i)\),以及\(i\)号点到\(2\)号点的方案数\(g(i)\);

如果一条起点为\(a_i\),终点为\(b_i\),长度为\(c_i\)的边满足\(f(a_i)*g(b_i)==f(2)\)且\(dist_1(i)+c_i+dist_2(i)==dist_1(2)\)则该边是原图中从\(1\)号点到\(2\)号的最短路径的必经之路。

将第i条边反向后对该边进行分类讨论

\(1.dist_2(ai)+dist_1(bi)+ci < dist_1(2)\) 则最短路径的长度变短了

\(2.dist_2(ai)+dist_1(bi)+ci == dist_1(2)\) ,则最短路径的长度并没有发生变化

\(3.dist_2(ai)+dist_1(bi)+ci > dist_1(2)\)

\(a.\)如果该边不是原图最短路径的必经之路,则最短路径的长度并没有发生变化

\(b.\)如果该边是原图最短路径的必经之路,则最短路径的长度变长了或者新图中不存在从\(1\)号点到\(2\)号点的路径

(当不存在从\(1\)号点到\(i\)号点的路径时,\(dist_1(i)\)为极大值,\(dist_2(i)\)同理)

时间复杂度\(O((m+n)log(n))\),但当路径数量过多时,\(f\)值和\(g\)值会超出\(int\)的储存范围

期望\(100\)分解法:

在上述求必经之路的时候用拓扑序或者其他方法求在最短路径构成的图上的桥

但是我太傻逼了,唉!

代码:

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int n,m,x[100001],y[100001],cnt,ans[100001],z[100001],dis[100001],dis1[100001],pre[100001],nxt[100001],h[100001],v[100001],c[100001],sum,in[100001],pree[100001],nxtt[100001],hh[100001],vv[100001],f[100001],g[100001];
struct oo{int x,y;};bool vis[100001];
bool operator<(oo a,oo b){return a.x>b.x;}
priority_queue<oo>q;
void add(int x,int y,int z){pre[++cnt]=y;nxt[cnt]=h[x];h[x]=cnt;v[cnt]=z;}
void ins(int x,int y,int z){pree[++cnt]=y;nxtt[cnt]=hh[x];hh[x]=cnt;vv[cnt]=z;}
void dijkstra(int x,int *dis,int id)
{
memset(vis,0,sizeof vis);
q.push((oo){0,x});dis[x]=0;
while(!q.empty())
{
oo x=q.top();q.pop();
if(vis[x.y])continue;vis[x.y]=1;
for(int i=h[x.y];i;i=nxt[i])
if(dis[pre[i]]>dis[x.y]+v[i])
{
dis[pre[i]]=dis[x.y]+v[i];
q.push((oo){dis[pre[i]],pre[i]});
}
}
}
void topsort(int x,int *f)
{
queue<int>que;
que.push(x);f[x]=1;
while(!que.empty())
{
int now=que.front();que.pop();
for(int i=hh[now];i;i=nxtt[i])
{
f[pree[i]]+=f[now];
if(!(--in[pree[i]]))que.push(pree[i]);
}
}
}
int main()
{
// freopen("route.in","r",stdin);
// freopen("route.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)scanf("%d%d%d",&x[i],&y[i],&z[i]),add(y[i],x[i],z[i]);
memset(dis1,63,sizeof dis1);memset(dis,63,sizeof dis);
dijkstra(2,dis1,0);
memset(h,0,sizeof h);cnt=0;
for(int i=1;i<=m;i++)add(x[i],y[i],z[i]);
dijkstra(1,dis,1);cnt=0;
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++)
for(int j=h[i];j;j=nxt[j])
if(dis[i]+v[j]+dis1[pre[j]]==dis[2])vis[j]=1,ins(i,pre[j],v[j]),x[cnt]=i,y[cnt]=pre[j],z[cnt]=v[j],in[pre[j]]++;
topsort(1,f);
memset(hh,0,sizeof hh);memset(in,0,sizeof in);int sum=cnt;cnt=0;
for(int i=1;i<=sum;i++)ins(y[i],x[i],z[i]),in[x[i]]++;
topsort(2,g);
for(int i=1;i<=n;i++)
for(int j=h[i];j;j=nxt[j])
{
if(vis[j]){if(f[i]*g[pre[j]]==f[2])ans[j]=1;}
else if(dis1[i]+v[j]+dis[pre[j]]<dis[2])ans[j]=-1;
}
for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
}

最新文章

  1. CGrowableArray解析 _ DXUT容器
  2. 一个iOS项目中包含多个xcodeproj文件,如何运行其中的一个项目
  3. 面向对象分析设计-------02UML+UML各种图形及作用
  4. Accepted Necklace
  5. 常见的NoSql系统使用场景分析--转载
  6. PHP漏洞全解(二)-命令注入攻击
  7. 日志收集框架 Exceptionless
  8. 递归:汉诺塔 - 零基础入门学习Python024
  9. asp.net笔记
  10. [SOJ] 图的广度优先搜索
  11. SDWebImage源码解读之分类
  12. 使用Word进行文档修订版本的比较
  13. jQuery中foreach的continue和break
  14. WebSphere--定制配置
  15. 协程与Epoll的配合
  16. HDU - 1540 Tunnel Warfare(线段树区间合并)
  17. XWIKI部署安装
  18. windows环境下最简单的nginx + tomcat负载均衡配置示例
  19. POJ 1611(并查集+知识)
  20. windows域相关

热门文章

  1. 2017NOIP游记 (格式有点炸)
  2. platform_set_drvdata()/platform_get_drvdata()/container_of()【转】
  3. UVA11551 Experienced Endeavour —— 矩阵快速幂
  4. awk 根据外部变量匹配某一域值
  5. hdu Integer Inquiry 解题报告
  6. html5--4-5 embed元素及其他
  7. tflearn 中文汉字识别,训练后模型存为pb给TensorFlow使用——模型层次太深,或者太复杂训练时候都不会收敛
  8. BZOJ_2730_ [HNOI2012]矿场搭建_点双联通分量
  9. 「LuoguP1430」 序列取数(区间dp
  10. MongoDB安装及多实例启动