AcWing 342 && BZOJ2200 roads and routes (fourth start over)

Topic Link  https://www.acwing.com/problem/content/344/

Title Description

Farmer John is a new sales area for his milk sales program to investigate.

T he wanted to milk towns, numbered 1 ~ T.

Urban road between the article by R (numbered 1 to R) and P routes (numbered 1 to P) connection.

I i each road or route connecting the town to Ai Bi, spent as Ci.

For the road, 0≤Ci≤10,000; however, it takes a very magical route, take CiCi may be negative (-10,000≤Ci≤10,000).

The road is two-way, from Ai to Bi, also from Bi to Ai, spend all Ci.

However, airline contrast, only from Ai to Bi.

In fact, due to the recent terrorist arrogant, for social harmony, introduced a number of policy: to ensure that if there is a route from Ai to Bi, then the guarantee can not return from Ai Bi by a number of roads and routes.

Because cows John recognized the world is to force, he needs to transport cows to every town.

He wanted to find the cheapest plan from the town center to send the cows to the S of each town.

Input Format

The first row contains four integers T, R, P, S.

Next R rows, each row containing three integers (representing a road) Ai, Bi, Ci.

Subsequently P rows, each row containing three integers (a route represented) Ai, Bi, Ci.

Output Format

1..T first line: the i-th line reaches the minimum cost towns i output from S, if not, outputs "NO PATH".

answer:

First %%% lydrainbow 

Explicitly said, there is a negative side, so he Dijkstra GG, but it has SPFA. Since lydrainbow when the data on this topic for a special data structure, and therefore he also SPFA the GG. The title indicates that only the negative side will have a one-way side for a DAG, seeking the shortest path based on the topology can be solved in linear time sequence, in fact, to go again to update the topology sequence, for example, the distance was completed recently after.

This method can be applied to this problem, but the problem is not the view of a DAG how to do? ? ? Since no negative side first bidirectional edge, the edge can be read first two-way, constituting an undirected graph, then block seek undirected graph, each of the communication block shrunk to a point, has to read the edge, is obtained a DAG. For this DAG can find the shortest sequence topology, and the point within each block may be communicated through the stack optimized Dijkstra shortest seek, in fact, very simple, it is to compute the shortest path in the course of seeking the topology of the sequence.

First, find the DAG for all the degree of communication block 0 point is located, and the communication block enqueued S (start point) where the (required topological order), and then sequentially removed from the queue a point (this point represents a communication block), then find the points belonging to this communication block, find their shortest. If the solving process encountered a communication block belongs to the same point, it is placed in the stack continue to solve, if not within the communication block described unidirectional edge, this will block communication of the point at which 1 is subtracted If the degree is 0, then the team (to solve the topological order process).

/**
 * Author : correct
 */
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
struct p{
	int x, dist;
	p(int x, int dist){this->x = x; this->dist = dist;}
	p(){}
	bool operator < (const p& a)const{return this->dist < a.dist;}
	bool operator > (const p& a)const{return this->dist > a.dist;}
};
#define ll long long
#define DEBUG cout << "----------------------------------------------\n"
#define mem(a, b) memset(a, b, sizeof a)
const int N = 25100, M = 50100 * 3, INF = 0x3f3f3f3f;
int head[N], nex[M], to[M], ed[M], cnt, belong[N], scc;
bool vis[N];
int in[N];
ll d[N];
queue<int > q;
priority_queue<p, vector<p>, greater<p> > pq;
void add(int a, int b, int c){
	++cnt;
	ed[cnt] = c;
	to[cnt] = b;
	nex[cnt] = head[a];
	head[a] = cnt;
}
void dfs(int x){
	belong[x] = scc;
	for (int i = head[x]; i; i = nex[i]){
		int y = to[i];
		if (!belong[y])dfs(y);
	}
}
int T, R, P, S;
int main(){
	freopen("in.in", "r", stdin);
	cnt = 0;
	scc = 0;
	mem(d, 0x3f);
#ifdef DEBUG
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
#endif
	cin >> T >> R >> P >> S;
	d[S] = 0;
	for (int i = 1; i <= R; i++){
		int a, b, c;
		cin >> a >> b >> c;
		add(a, b, c);
		add(b, a, c);
	}
	for (int i = 1; i <= T; i++){
		if (!belong[i]){
			++scc;
			dfs(i);
		}
	}
	for (int i = 1; i <= P; i++){
		int a, b, c;
		cin >> a >> b >> c;
		add(a, b, c);
		in[belong[b]]++;
	}
	q.push(belong[S]);

	for (int i = 1; i <= scc; i++){
		if (in[i] == 0)q.push(i);
	}
	while (q.size()){
		int ft = q.front();
		q.pop();
		for (int i = 1; i <= T; i++){
			if (belong[i] == ft){
				pq.push(p(i, d[i]));
			}
		}
		while (pq.size()){
			p t = pq.top();
			pq.pop();
			if (vis[t.x])continue;
			vis[t.x] = 1;
			for (int i = head[t.x]; i; i = nex[i]){
				int y = to[i];
				int c = ed[i];
				if (d[y] > d[t.x] + c){
					d[y] = d[t.x] + c;
					if (belong[y] == belong[t.x]){
						pq.push(p(y, d[y]));
					}
				}
				if (belong[y] != belong[t.x]){
					in[belong[y]]--;
					if (in[belong[y]] == 0){
						q.push(belong[y]);
					}
				}
			}
		}
	}
	for (int i = 1; i <= T; i++){
		if (d[i] >= INF)cout << "NO PATH\n";
		else cout << d[i] << "\n";
	}
	return 0;
}

I checked the troubleshooting afternoon and found a very wrong place at the sand sculpture. The first step in looking into the degree of communication block where the point of zero, it should traverse all, I traversed, but I use the loop variable i is a non-circulation of other variables instead.

Published 204 original articles · won praise 13 · views 10000 +

Guess you like

Origin blog.csdn.net/weixin_43701790/article/details/105129718