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


    • 题意:有一张有向图,每个点的权值为点(1)到该点的最短距离(每条边的长度为(1)),对于一条路径,这条路径上最多只能有一条边,这条边起点的权值不小于终点,现在要求每个点能到达路径上的点的最小权值.
    • 题解:首先我们先用bfs求出每个点的权值,并且在求的同时用桶将点存起来,方便之后枚举权值的时候用,然后我们可以将权值从大到小枚举,记(dp_i)是当前这个点能到达路径上的点的最小权值,对于当前的点(u)和它的出边(v),如果(dis[u] < dis[v]),那么我们是可以继续随便走的,所以当前状态应该是(dp[u]=min(dp[u],dp[v])),否则,说明我们将第二次机会用掉了,之后就只能选择第一种操作,所以我们更新的时候就不能将(dp[v])(因为是从大到小枚举,所以(dp[v])的状态一定是已知的)更新给当前状态,因为我们不知道(dp[v])这个状态是否还用了第二次操作,所以当前状态就应该更新为(dp[u]=min(dp[u],dis[v])).
    • 代码:
    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
    
    int t;
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    
    	cin>>t;
    	while(t--){
    		int n,m;
    		cin>>n>>m;
    
    		vector<vector<int>> v(n+1);
    		vector<vector<int>> tot(n+1);
    		vector<int> dis(n+1,INF);
    		vector<int> dp(n+1);
    		
    		int a,b;
    
    		rep(i,1,m){
    			cin>>a>>b;
    			v[a].pb(b);
    		}
    
    		queue<int> q;
    		q.push(1);
    		dis[1]=0;
    
    		//bfs init
    		while(!q.empty()){
    			int cur=q.front();
    			q.pop();
    			for(auto w : v[cur]){
    				if(dis[cur]+1<dis[w]){
    					dis[w]=dis[cur]+1;
    					tot[dis[w]].pb(w);
    					q.push(w);
    				}
    			}
    		}
    
    		rep(i,1,n){
    			dp[i]=dis[i];
    		}	
    
    		per(i,n-1,1){
    			for(auto u : tot[i]){
    				for(auto w : v[u]){
    					if(dis[w]>dis[u]) dp[u]=min(dp[u],dp[w]);
    					else dp[u]=min(dp[u],dis[w]);
    				}
    			}
    		}
    
    		rep(i,1,n) cout<<dp[i]<<' ';
    		cout<<'
    ';
    
    	}
    
        return 0;
    }
    
    
  • 相关阅读:
    PAT甲级——1095 Cars on Campus (排序、映射、字符串操作、题意理解)
    PAT甲级——1096 Consecutive Factors (数学题)
    PAT甲级——1097 Deduplication on a Linked List (链表)
    博客作业06--图
    博客作业05--查找
    博客作业04--树
    博客作业03--栈和队列
    博客作业2---线性表
    博客作业01-抽象数据类型
    C语言最后一次作业--总结报告
  • 原文地址:https://www.cnblogs.com/lr599909928/p/14297943.html
Copyright © 2011-2022 走看看