POJ 3114 Countries in War(强连通+最短路)

POJ 3114 Countries in War

题目链接

题意:给定一个有向图,强连通分支内传送不需要花费,其他有一定花费,每次询问两点的最小花费

思路:强连通缩点后求最短路即可

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;

const int MAXNODE = 505;
const int MAXEDGE = 255005;

typedef int Type;
const Type INF = 0x3f3f3f3f;

struct Edge {
	int u, v;
	Type dist;
	Edge() {}
	Edge(int u, int v, Type dist) {
		this->u = u;
		this->v = v;
		this->dist = dist;
	}
};

struct HeapNode {
	Type d;
	int u;
	HeapNode() {}
	HeapNode(Type d, int u) {
		this->d = d;
		this->u = u;
	}
	bool operator < (const HeapNode& c) const {
		return d > c.d;
	}
};

struct Dijkstra {
	int n, m;
	Edge edges[MAXEDGE];
	int first[MAXNODE];
	int next[MAXEDGE];
	bool done[MAXNODE];
	Type d[MAXNODE];

	void init(int n) {
		this->n = n;
		memset(first, -1, sizeof(first));
		m = 0;
	}

	void add_Edge(int u, int v, Type dist) {
		edges[m] = Edge(u, v, dist);
		next[m] = first[u];
		first[u] = m++;
	}

	int dijkstra(int s, int t) {
		priority_queue<HeapNode> Q;
		for (int i = 0; i < n; i++) d[i] = INF;
		d[s] = 0;
		memset(done, false, sizeof(done));
		Q.push(HeapNode(0, s));
		while (!Q.empty()) {
			HeapNode x = Q.top(); Q.pop();
			int u = x.u;
			if (u == t) return d[t];
			if (done[u]) continue;
			done[u] = true;
			for (int i = first[u]; i != -1; i = next[i]) {
				Edge& e = edges[i];
				if (d[e.v] > d[u] + e.dist) {
					d[e.v] = d[u] + e.dist;
					Q.push(HeapNode(d[e.v], e.v));
				}
			}
		}
		return -1;
	}
} gao;

const int N = 505;

int n, m;
vector<Edge> g[N];

int pre[N], dfn[N], dfs_clock, sccn, sccno[N];
stack<int> S;

void dfs_scc(int u) {
	pre[u] = dfn[u] = ++dfs_clock;
	S.push(u);
	for (int i = 0; i < g[u].size(); i++) {
		int v = g[u][i].v;
		if (!pre[v]) {
			dfs_scc(v);
			dfn[u] = min(dfn[u], dfn[v]);
		} else if (!sccno[v]) dfn[u] = min(dfn[u], pre[v]);
	}
	if (pre[u] == dfn[u]) {
		sccn++;
		while (1) {
			int x = S.top(); S.pop();
			sccno[x] = sccn;
			if (x == u) break;
		}
	}
}

void find_scc() {
	dfs_clock = sccn = 0;
	memset(sccno, 0, sizeof(sccno));
	memset(pre, 0, sizeof(pre));
	for (int i = 1; i <= n; i++)
		if (!pre[i]) dfs_scc(i);
}

int main() {
	while (~scanf("%d%d", &n, &m) && n) {
		for (int i = 1; i <= n; i++) g[i].clear();
		int u, v, w;
		while (m--) {
			scanf("%d%d%d", &u, &v, &w);
			g[u].push_back(Edge(u, v, w));
		}
		find_scc();
		gao.init(n);
		for (int u = 1; u <= n; u++) {
			for (int j = 0; j < g[u].size(); j++) {
				int v = g[u][j].v;
				if (sccno[u] == sccno[v]) continue;
				gao.add_Edge(sccno[u] - 1, sccno[v] - 1, g[u][j].dist);
			}
		}
		int q;
		scanf("%d", &q);
		while (q--) {
			scanf("%d%d", &u, &v);
			int tmp = gao.dijkstra(sccno[u] - 1, sccno[v] - 1);
			if (tmp == -1) printf("Nao e possivel entregar a carta\n");
			else printf("%d\n", tmp);
		}
		printf("\n");
	}
	return 0;
}
时间: 2024-10-14 08:23:26

POJ 3114 Countries in War(强连通+最短路)的相关文章

POJ 3114 Countries in War 强连通+最短路

用floyd超时了...注定的事情...题意:看案例就跑出来了..不需要看题了把.. #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #include<vector> const int INF =1999299; int minn(int a,int b) { return a>b?b:a; } #define N 510 #define M

POJ 3114 - Countries in War(强连通分量+缩点+拓扑排序+DAG最短路)

Countries in War Time Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Appoint description: Description In the year 2050, after different attempts of the UN to maintain peace in the world, the third world war broke out. The impor

POJ 3114 Countries in War(强连通分量+最短路)

题目大意: n个间谍 他们之间传送信息需要一定的时间一个联通分量里面的间谍属于一个国家,之间的信息传递不需要时间然后问你从一个间谍传一个信息到另一个间谍那需要最少时间 也可能传不到 思路:先缩点,再最短路,由于n最大只有500.可以用邻接矩阵,而且对缩点后的DAG的边权可以做贪心处理,只留两个强连通分量间的最短边长即可. //2852K 297MS C++ 2595B #include<cstdio> #include<iostream> #include<cstring&g

POJ 3114 Countries in War(强联通分量+Tarjan)

题目链接 题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0. 思路 :强连通分量缩点之后,求最短路.以前写过,总感觉记忆不深,这次自己敲完再写了一遍. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <vector> 5 #include <stack> 6 #include <queue> 7 #inc

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

题目链接 题意是说在几个邮局之间传送一份信件,如果出发点和终止点在同一个国家传递,则时间为0,否则让你求花费最少时间,如果不能传到,则输出Nao e possivel entregar a carta.判断邮局是否在同一个国家的依据是发出的信件可以相互到达. 如果直接求最短路则无法判断两个邮局是否在同一个国家,判断两个邮局是否属于同一个国家的标志是在这个国家邮局间可以相互到达,那么这就是强连通了,所以要先缩点判读邮局是否在同一个国家,如果不是,则重新建图,建图的时候要维护好边权,求出最短边权,在

poj 3114(korasaju算法和dij算法)

Countries in War Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2407   Accepted: 751 Description In the year 2050, after different attempts of the UN to maintain peace in the world, the third world war broke out. The importance of indus

【POJ】2449 Remmarguts&#39; Date(k短路)

http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k 首先我们建反向边,跑一次从汇到源的最短路,将跑出来的最短路作为估价函数h 根据f=g+h 我们将源s先走,此时实际价值g为0,估价为最短路(他们的和就是s-t的最短路) 将所有s所连的边都做相同的处理,加入到堆中(假设此时到达的点为x,那么x的g等于s到这个点的边权,因为根据最优,g+h此时是从x

Poj 1904 King&#39;s Quest 强连通分量

题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可以取哪些公主,并且保证取了一个公主后,全局还是存在完美匹配. 题解: 1.建图: 如果王子u对公主v心仪,则连一条边u->v.在样例给出的那组完美匹配中,如果王子u娶了公主v,连一条边v->u. 2.求强连通分量: 如果王子和自己心仪的公主属于同一个强连通分量,那么王子就可以娶这个公主. 1 #i

POJ - 1904 King&#39;s Quest(强连通分量+二分图匹配)

题目大意:有N个帅哥和N个美女,现在给出每个帅哥所喜欢的美女的编号,和一个帅哥和美女的完美匹配 问每个帅哥可以娶多少个美女,且当他娶完这个美女后,剩下的人还可以完美匹配 解题思路:神题啊,给一个大神的详细解答 具体是这样的,首先先建边,把帅哥和能娶到的美女连边,再把完美匹配的美女和帅哥连边,这样就形成了一张有向图了 接着,找出这张有向图的所有强连通分量,在强连通分量里面的帅哥都可以娶到自己喜欢的美女,且娶完这个美女后,不会影响到其他人 为什么呢? 假设xi为帅哥,yi和yj为美女,假设给定的完美