首页 > 其他分享 >P1841

P1841

时间:2024-11-18 21:58:34浏览次数:1  
标签:node 10 删除 int 短路 P1841 dis

P1841

给定一张图,求有多少点满足,删除该点之后存在两点的最短路被改变。该两点均不为被删除的点。

\(n \le 300, m \le n(n-1)/2\)


对于一个起点 \(s\),建出最短路图。因此 \(c>0\),所以必然是 DAG。现在问题转化成:在 DAG 上每次考虑删除一个点,是否会出现 \(s\) 无法到一个原来能够到达的点?

这里我当时出的问题很乐。枚举起点是 \(O(n)\),枚举删除的点也是 \(O(n)\) 的。当时我每次都跑一个 dfs,以为自己 \(O(n^2(n+m))\)。但是 \(m\) 是 \(n^2\) 级别的。

最短路图满足起点到任意一个点均有通路。删除一个点 \(u\) 无法到达别的点的充要条件是存在边 \((u, v)\),使得 \(v\) 的入度为 1。这是容易证明的:因为 \(v\) 入度为 \(1\),所以 \(s\) 到 \(v\) 只有一条通路。删除 \(u\) 就会消除这条通路。从而到不了。

画画图是容易得到结论的

#include <bits/stdc++.h>
using namespace std;
const int N = 200, inf = 2e6;
struct node {
	int to, val;
	node(int T, int V) {
		to = T, val = V;
	}
};
vector <node> gra[N + 10];
bool br[N + 10], vis[N + 10];
int dis[N + 10], n, m, deg[N + 10];
void dij(int s) {
	for(int i = 1; i <= n; i++)
		dis[i] = inf, vis[i] = 0;
	dis[s] = 0;
	

	for(int i = 1; i <= n; i++) {
		int x = 0;
		for(int j = 1; j <= n; j++)
			if(!vis[j] && ((x == 0) || (dis[j] < dis[x])))
				x = j;
		vis[x] = 1;

		for(int j = 0; j < gra[x].size(); j++) {
			int v = gra[x][j].to, w = gra[x][j].val;
			if(dis[v] > dis[x] + w)
				dis[v] = dis[x] + w;
		}
	}

	for(int i = 1; i <= n; i++)
		if(dis[i] >= inf) vis[i] = 0;
}
void work(int s) {
	dij(s);
	for(int u = 1; u <= n; u++) deg[u] = 0;
	for(int u = 1; u <= n; u++) {
		for(int i = 0; i < gra[u].size(); i++) {
			int v = gra[u][i].to, w = gra[u][i].val;
			if(dis[v] == dis[u] + w) deg[v]++;
		}
	}
	for(int u = 1; u <= n; u++) {
		if(br[u]) continue;
		for(int i = 0; i < gra[u].size(); i++) {
			int v = gra[u][i].to, w = gra[u][i].val;
			if(dis[v] != dis[u] + w) continue;
			if(deg[v] == 1 && u != s) br[u] = 1;
		}
	}
}
int main() {
	cin >> n >> m;
	for(int i = 1, x, y, z; i <= m; i++) {
		cin >> x >> y >> z;
		gra[x].push_back(node(y, z));
		gra[y].push_back(node(x, z));
	}
	for(int i = 1; i <= n; i++)
		work(i);
	int cnt = 0;
	for(int i = 1; i <= n; i++)
		if(br[i]) cout << i << ' ', cnt++;
	if(!cnt) {
		cout << "No important cities." << endl;
		return 0;
	}
}

总结

  1. 最短路图在结构上有一些可能较为特别的性质
  • 只有起点入度为 \(0\)。
  • 起点到每个点均有通路。
  1. 一定要注意稠密图中 \(m\) 是 \(n^2\) 级别的。

标签:node,10,删除,int,短路,P1841,dis
From: https://www.cnblogs.com/thirty-two/p/18553766

相关文章