http://poj.org/problem?id=3114

题意:有n个城市,m条边,由a城市到b城市的通信时间为w,若a城市与b城市连通,b城市与a城市也连通,则a,b城市之间的通信时间为0,求出从s到t的最少通信时间。

思路:先由Tarjan算法求出图中的连通分量,则在同一个连通分量里的城市之间的通信时间w更新为0,然后利用spfa求出s城市与t城市之间的最短路,即为最少通信时间。

 #include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <stack>
const int N=;
const int INF=<<;
using namespace std;
struct node
{
int u,v,w;
int next;
} edge[N*N];
//dfn[i]表示点i的深度优先数;
int dfn[N],low[N],head[N]; //low[i]表示点i可到达的最低深度优先数
int Conn_num[N],vis[N],dis[N];//Conn_num[i]表示点i所属的连通分量的编号;
int n,m,cnt,dfs_clock,Conn_cnt;
stack<int>S; void init()
{
cnt = ;
dfs_clock = ;
Conn_cnt = ;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(vis,,sizeof(vis));
memset(Conn_num,,sizeof(Conn_num));
memset(head,-,sizeof(head));
}
void add(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 dfs(int u)//Tarjan算法
{
dfn[u]=low[u]=++dfs_clock;//设定初值
S.push(u);//将节点u压入栈中
for (int i = head[u]; i!=-; i=edge[i].next)//遍历u的临接点
{
int v = edge[i].v;
if (!dfn[v])//如果改点的深度优先数为0(即没有搜索过)
{
dfs(v);//继续向下找
low[u] = min(low[u],low[v]);//回溯过程中计算low[]的值
}
else if(!Conn_num[v])//v不在连通分量中,即v还在栈中
{
low[u] = min(low[u],dfn[v]);
}
}
if (dfn[u]==low[u])//找到一个连通分量
{
++Conn_cnt;//连通分量计数
while()//将栈里属于同一个连通分量的点弹出
{
int v = S.top();
S.pop();
Conn_num[v] = Conn_cnt;//表示点v在第Conn_cnt个连通分量里
if (v==u)
break;
}
}
}
void spfa(int s)//缩点后求最短路
{
queue<int>q;
for (int i = ; i <= n; i++)
{
dis[i] = INF;
vis[i] = ;
}
dis[s] = ;
q.push(s);
vis[s] = ;
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = ;
for (int j = head[u]; j!=-; j = edge[j].next)
{
int v = edge[j].v;
int w = edge[j].w;
if(Conn_num[u]==Conn_num[v])//如果属于同一个连通分量,其权值为0
w = ;
if (dis[v]>dis[u]+w)
{
dis[v] = dis[u]+w;
if (!vis[v])
{
q.push(v);
vis[v] = ;
}
}
}
}
}
int main()
{
int s,t;
int u,v,w,k;
while(~scanf("%d%d",&n,&m))
{
if (n==&&m==)
break;
init();
for (int i = ; i < m; i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
for (int i = ; i <= n; i++)
{
if (!dfn[i])
dfs(i);
}
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&s,&t);
if (Conn_num[s]==Conn_num[t])
printf("0\n");
else
{
spfa(s);
if(dis[t] >= INF)
printf("Nao e possivel entregar a carta\n");
else
printf("%d\n",dis[t]);
}
}
printf("\n");
}
return ;
}

Countries in War(强连通分量及其缩点)的更多相关文章

  1. POJ3114 Countries in War (强连通分量 + 缩点 + 最短路径 + 好题)

    题目链接 题意是说在几个邮局之间传送一份信件,如果出发点和终止点在同一个国家传递,则时间为0,否则让你求花费最少时间,如果不能传到,则输出Nao e possivel entregar a carta ...

  2. Tarjan求强连通分量,缩点,割点

    Tarjan算法是由美国著名计算机专家发明的,其主要特点就是可以求强连通分量和缩点·割点. 而强联通分量便是在一个图中如果有一个子图,且这个子图中所有的点都可以相互到达,这个子图便是一个强连通分量,并 ...

  3. POJ-2186-Popular Cows(强连通分量,缩点)

    链接:https://vjudge.net/problem/POJ-2186 题意: 有N(N<=10000)头牛,每头牛都想成为most poluler的牛,给出M(M<=50000)个 ...

  4. Instantaneous Transference(强连通分量及其缩点)

    http://poj.org/problem?id=3592 题意:给出一个n*m的矩阵,左上角代表起始点,每个格子都有一定价值的金矿,其中‘#’代表岩石不可达,‘*’代表时空门可以到达指定格子,求出 ...

  5. Tarjan算法求有向图强连通分量并缩点

    // Tarjan算法求有向图强连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> #inc ...

  6. Countries in War (POJ 3114) Tarjan缩点+最短路

    题目大意: 在一个有向图中,每两点间通信需要一定的时间,但同一个强连通分量里传递信息不用时间,给两点u,v求他们最小的通信时间.   解题过程: 1.首先把强连通分量缩点,然后遍历每一条边来更新两个强 ...

  7. [HDOJ1827]Summer Holiday(强连通分量,缩点)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1827 缩点后统计入度和当前强连通分量中最小花费,然后记录入度为0的点的个数和花费和就行了. /* ━━ ...

  8. 强连通分量tarjan缩点——POJ2186 Popular Cows

    这里的Tarjan是基于DFS,用于求有向图的强联通分量. 运用了一个点dfn时间戳和low的关系巧妙地判断出一个强联通分量,从而实现一次DFS即可求出所有的强联通分量. §有向图中, u可达v不一定 ...

  9. POJ 1236 Network of Schools(强连通分量/Tarjan缩点)

    传送门 Description A number of schools are connected to a computer network. Agreements have been develo ...

随机推荐

  1. 前端安全 xss

    整体的 XSS 防范是非常复杂和繁琐的,不仅需要在全部需要转义的位置,对数据进行对应的转义.而且要防止多余和错误的转义,避免正常的用户输入出现乱码. 虽然很难通过技术手段完全避免 XSS,但可以总结以 ...

  2. UVA - 247 Calling Circles(Floyd求传递闭包)

    题目: 思路: 利用Floyd求传递闭包(mp[i][j] = mp[i][j]||(mp[i][k]&&mp[k][j]);),当mp[i][j]=1&&mp[j][ ...

  3. Haoop Mapreduce 中的FileOutputFormat类

    FileOutputFormat类继承OutputFormat,需要提供所有基于文件的OutputFormat实现的公共功能,主要有以下两点: (1)实现checkOutputSpecs方法 chec ...

  4. Linux mpstat-显示各个可用CPU的状态

    更多linux 性能监测与优化 关注:linux命令大全 mpstat命令指令主要用于多CPU环境下,它显示各个可用CPU的状态系你想.这些信息存放在/proc/stat文件中.在多CPUs系统里,其 ...

  5. buf.readUInt16BE()

    buf.readUInt16BE(offset[, noAssert]) buf.readUInt16LE(offset[, noAssert]) offset {Number} 0 <= of ...

  6. graph.h

    #ifndef _GRAPH_#define _GRAPH_#include<stdio.h>#include<stdlib.h>#include<string.h> ...

  7. 吧,其实spring自带的BeanUtils就有这样的功能,引入spring-beans和spring-core之后,就有BeanUtils.copyProperties(a, b);可以实现两个javabean之间的相互拷贝,自己写的就当是研究咯---https://www.cnblogs.com/NieXiaoHui/p/7150928.html

    吧,其实spring自带的BeanUtils就有这样的功能,引入spring-beans和spring-core之后,就有BeanUtils.copyProperties(a, b);可以实现两个ja ...

  8. 个人常用git命令

    最近开始使用git,将自己常用git命令做一个简单归纳,便于记忆. 初始化及配置 git init:初始化资料库 git config --global user.name 'xxx':配置用户名 g ...

  9. [Vue @Component] Switch Between Vue Components with Dynamic Components

    A common scenario is to present different components based on the state of the application. Dynamic ...

  10. Solidworks如何导入和使用模板文件

    将模板文件拷贝到Solidworks目录(可以是任意目录)     点击工具-选项-文件位置,然后把文件夹添加进去   新建文件的时候选择高级模式,然后就会看到已经出现了我们导入的模板文件       ...