zoukankan      html  css  js  c++  java
  • 【Codeforces Round #693 (Div. 3) G】Moving to the Capital

    题目链接

    链接

    翻译

    注意是有向图,不然这题读起来会觉得题目很奇怪。。

    题解

    bfs 求最短路 d[1..n],然后对于 (d_i<d_j) 的边连实线,否则连虚线。

    就可以做 dp 了,对于实线 dp[x] = min(dp[x],dp[y]),对于虚线 dp[x] = min(dp[x],d[y])

    虚线只能走一次嘛。然后实线还能顺着往下走。妥妥的记忆化,当然不要忘了待在原地不动的情况,对应 (dp[x]=min(dp[x],d[x]))

    代码

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    
    const int N = 2e5;
    const LL MOD = 1e9 + 7;
    const int K = 5000;
    
    int n, m, d[N+10],dp[N+10];
    vector<int> g[3][N + 10];
    queue<int> dl;
    
    void bfs() {
    	for (int i = 1; i <= n; i++) {
    		d[i] = n + 1;
    	}
    	d[1] = 0;
    	dl.push(1);
    	while (!dl.empty()) {
    		int x = dl.front();
    		dl.pop();
    		int len = g[0][x].size();
    		for (int y : g[0][x]) {
    			if (d[y] == n + 1) {
    				d[y] = d[x] + 1;
    				dl.push(y);
    			}
    		}
    	}
    }
    
    int dfs(int x) {
    	if (dp[x] != n + 1) {
    		return dp[x];
    	}
    	//实线可以任意走。
    	for (int y : g[1][x]) {
    		dp[x] = min(dp[x], dfs(y));
    	}
    	//虚线只能走一次。
    	for (int y : g[2][x]) {
    		dp[x] = min(dp[x], d[y]);
    	}
    	//待在原地
    	dp[x] = min(dp[x], d[x]);
    	return dp[x];
    }
    
    int main() {
    	#ifdef LOCAL_DEFINE
    		freopen("in.txt", "r", stdin);
    	#endif
    	ios::sync_with_stdio(0), cin.tie(0);
    	int T;
    	cin >> T;
    	while (T--) {
    		cin >> n >> m;
    		for (int i = 1; i <= n; i++) {
    			for (int j = 0; j < 3; j++) {
    				g[j][i].clear();
    			}
    		}
    		for (int i = 1; i <= m; i++) {
    			int x, y;
    			cin >> x >> y;
    			g[0][x].push_back(y);
    		}
    		bfs();
    		for (int x = 1; x <= n; x++) {
    			for (int y : g[0][x]) {
    				if (d[y] > d[x]) {
    					g[1][x].push_back(y);
    				}
    				else {
    					//虚线
    					g[2][x].push_back(y);
    				}
    			}
    		}
    		for (int i = 1; i <= n; i++) {
    			dp[i] = n + 1;
    		}
    		for (int i = 1; i <= n; i++) {
    			if (dp[i] == n + 1) {
    				dp[i] = dfs(i);
    			}
    		}
    		for (int i = 1; i <= n; i++) {
    			cout << dp[i] << " ";
    		}
    		cout << endl;
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    BZOJ_2460_[BeiJing2011]元素_线性基
    BZOJ_4448_[Scoi2015]情报传递_主席树
    BZOJ_4004_[JLOI2015]装备购买_线性基
    BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组
    BZOJ_4128_Matrix_矩阵乘法+哈希+BSGS
    BZOJ_4378_[POI2015]Logistyka_树状数组
    BZOJ_2527_[Poi2011]Meteors_整体二分
    BZOJ_2738_矩阵乘法_整体二分
    BZOJ_3687_简单题_bitset
    HDU 4501
  • 原文地址:https://www.cnblogs.com/AWCXV/p/14264321.html
Copyright © 2011-2022 走看看