题目链接

题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0.

思路 :强连通分量缩点之后,求最短路。以前写过,总感觉记忆不深,这次自己敲完再写了一遍。

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#define maxn 505
using namespace std ; struct node
{
int u,v,w,next ;
} edge[maxn*maxn];
int p[maxn][maxn];
int dfn[maxn],low[maxn],head[maxn] ,vis[maxn],dis[maxn],belong[maxn];
int timee,cnt ,cntt,n,m;
stack<int>stk ; void Init()
{
timee = ;
cnt = cntt = ;
memset(dfn,,sizeof(dfn)) ;
memset(low,,sizeof(low)) ;
memset(dis,,sizeof(dis)) ;
memset(head,-,sizeof(head)) ;
memset(vis,,sizeof(vis)) ;
memset(p,0x3f,sizeof(p)) ;
}
void addedge(int u,int v,int w)
{
edge[cnt].u = u ;
edge[cnt].v = v ;
edge[cnt].w = w ;
edge[cnt].next = head[u] ;
head[u] = cnt++ ;
}
void tarjan(int u)
{
//cout<<u<<endl;
int v ;
vis[u] = ;
dfn[u] = low[u] = ++ timee ;
stk.push(u) ;
for(int i = head[u] ; i != - ; i = edge[i].next)
{
v = edge[i].v ;
if(!dfn[v])
{
//printf("v = %d\n",v) ;
tarjan(v) ;
low[u] = min(low[v],low[u]) ;
}
else if(vis[v])
low[u] = min(low[u],dfn[v]) ;
}
if(low[u] == dfn[u])
{
cntt ++ ;
do
{
v = stk.top() ;
stk.pop() ;
vis[v] = ;
belong [v] = cntt ;
// puts("1") ;
}
while(v != u) ;
}
}
void SPFA(int u,int v)
{
queue<int>Q ;
for(int i = ; i <= cntt ; i++)
{
dis[i] = ;
vis[i] = ;
}
dis[u] = ;
vis[u] = ;
Q.push(u) ;
while(!Q.empty())
{
int s = Q.front() ;
Q.pop() ;
vis[s] = ;
for(int i = ; i <= n ; i ++ )
{
if(p[s][i] != )
{
if(dis[i] > dis[s] + p[s][i])
{
dis[i] = dis[s] + p[s][i] ;
if(!vis[i])
{
Q.push(i) ;
vis[i] = ;
}
}
}
}
}
if(dis[v] != )
printf("%d\n",dis[v]) ;
else printf("Nao e possivel entregar a carta\n") ;
}
void rebuild()
{
for(int i = ; i <= n ; i++)
{
for(int j = head[i] ; j != - ; j = edge[j].next)
{
// int s = edge[i].v ;
int v = belong[edge[j].v] ;
int u = belong[edge[j].u] ;
if(u != v)
p[u][v] = min(p[u][v],edge[j].w) ;
}
}
for(int i = ; i <= cntt ; i++)
p[i][i] = ;
}
int main()
{
int x,y,h,k;
while(~scanf("%d %d",&n,&m))
{
if(n == && m == ) break ;
Init() ;
for(int i = ; i < m ; i++)
{
scanf("%d %d %d",&x,&y,&h) ;
addedge(x,y,h) ;
}
for(int i = ; i <= n ; i++)
{
if(!dfn[i])
tarjan(i) ;
}
// cout<<"s"<<endl;
rebuild() ;
// cout<<"s"<<endl;
scanf("%d",&k) ;
for(int i = ; i < k ; i++)
{
//cout<<i<<endl;
scanf("%d %d",&x,&y) ;
SPFA(belong[x],belong[y]) ;
}
printf("\n") ;
}
return ;
}

最新文章

  1. 【JAVA并发编程实战】6、中断
  2. PHP正则表达式模式修饰符 /i, /is, /s, /isU等
  3. Unity学习疑问记录之隐藏与显示物体
  4. kindeditor-4.1.7应用
  5. Browser设置搜索引擎
  6. Javascript中的Prototype到底是啥
  7. Javascript日期时间总结
  8. 了解ThinkPHP(一)
  9. JavaScript--基本包装类型(13)
  10. 全球AI界最值得关注的十位科学家
  11. ASM - 条件判断
  12. Vulkan Tutorial 26 view and sampler
  13. 安装puppet
  14. ASP.NET Core 3.0预览版体验
  15. 2018-2019-2 网络对抗技术 20165335 Exp2 后门原理与实践
  16. Flask上下文
  17. CMFCToolBar、CMFCStatusBar
  18. Redis学习--Redis数据类型
  19. mysql学习笔记--数据库操作
  20. APP微信支付报错《商户号该产品权限未开通,请前往商户平台&gt;产品中心检查后重试》

热门文章

  1. AngularJS 授权 + Node.js REST api
  2. UIButton setImage setBackgoundImage
  3. Entity Framework SqlFunctions 教你如何在EF调用sqlserver方法的函数存根
  4. 实体框架 (EF) 入门 =&gt; 一、我该用哪个工作流?
  5. UITextField swift
  6. TList,TObjectList 使用——资源释放
  7. 寻找idea...
  8. Eigen库实现简单的旋转、平移操作
  9. JIRA安装过程中链接mysql的问题!
  10. Python中的计数(词频)