Poj 3114 countries in war
Question Link
Given a directed graph, it does not need to be consumed for transmission within a strongly connected branch. The minimum cost of two points is required for each query.
Idea: Find the shortest path after the strongly connected contraction point
Code:
#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;}
Poj 3114 countries in war (strongly connected + short circuit)