蓝桥杯练习题-《道路和航路》解题报告
题目链接:http://lx.lanqiao.org/problem.page?gpid=T22
题目描述如下:
农夫约翰正在针对一个新区域的牛奶配送合同进行研究。他打算分发牛奶到T个城镇(标号为1..T),这些城镇通过R条标号为(1..R)的道路和P条标号为(1..P)的航路相连。代码如下:
#include
#include
#include
#include
#include
#include
#include
#define clr(a,b) memset(a, b, sizeof(a))
using namespace std;
const int N = 25050;
const int E = 150500;
//邻接表
int h[N], v[E], w[E], nxt[E], el;
void initEdge() {
clr(h, -1); el = 0;
}
void addEdge(int x, int y, int z) {
v[el] = y; w[el] = z; nxt[el] = h[x]; h[x] = el++;
}
//并查集
int rt[N], ra[N];
int Find(int x) {
if(x != rt[x]) rt[x] = Find(rt[x]);
return rt[x];
}
void Union(int r1, int r2) {
int x = Find(r1), y = Find(r2);
if(x == y) return;
if(ra[x] > ra[y]) rt[y] = x;
else {
rt[x] = y;
if(ra[x] == ra[y]) ++ra[y];
}
}
void Init(int n) {
for(int i=0; i<=n; i++)
ra[i] = 0, rt[i] = i;
}
struct EDGE {
int u, v, w;
bool flag;
EDGE(){}
EDGE(int x, int y, int z, bool f):u(x), v(y), w(z), flag(f){}
} edge[E];
int edgel;
bool visitable[N];
void dfs(int x) {
visitable[x] = true;
for(int i=h[x]; ~i; i=nxt[i]) {
if(!visitable[v[i]]) {
dfs(v[i]);
}
}
}
int indegree[N];
bool vis[N];
//链表
int lh[N], lel, lv[E], lnxt[E];
void initLink() {
clr(lh, -1); lel = 0;
}
void addLink(int x, int y) {
lv[lel] = y; lnxt[lel] = lh[x]; lh[x] = lel++;
}
int dis[N];
bool tag[N];
int main() {
int n, r, p, s;
scanf("%d%d%d%d", &n, &r, &p, &s);
Init(n);
initEdge();
edgel = 0;
int x, y, z;
for(int i=0; i zeroDegree;
priority_queue > que;
clr(dis, 0x3f);
dis[s] = 0;
que.push(make_pair(0, s));
while(!que.empty() || !zeroDegree.empty()) {
if(que.empty()) {
int x = zeroDegree.top(); zeroDegree.pop();
for(int i=lh[x]; ~i; i=lnxt[i]) {
int y = lv[i];
if(!vis[y]) {
vis[y] = true;
que.push(make_pair(-dis[y], y));
}
}
} else {
int x = que.top().second; que.pop();
if(tag[x]) continue;
tag[x] = true;
for(int i=h[x]; ~i; i=nxt[i]) {
int y = v[i];
if(!tag[y] && dis[y] > dis[x] + w[i]) {
dis[y] = dis[x] + w[i];
if(Find(x) == Find(y)) {
que.push(make_pair(-dis[y], y));
}
}
if(Find(x) != Find(y)) {
-- indegree[Find(y)];
if(indegree[Find(y)] == 0) {
zeroDegree.push(Find(y));
}
}
}
}
}
for(int i=1; i<=n; i++) {
if(visitable[i]) {
printf("%d\n", dis[i]);
} else {
puts("NO PATH");
}
}
return 0;
}