zoukankan      html  css  js  c++  java
  • Luogu P1137 旅行计划

    Luogu P1137 旅行计划

    可以发现,因为只能往东边走,并且有入度为$0$的起点,因此这是一个有向无环图,可以进行拓扑排序,求出拓扑序列。
    那么我们要拓扑序列怎么做呢?由于拓扑序列中,前面的点总是后面的点的前驱,因此可以进行DP。
    而DP的状态转移方程也很明显,这个城市只能由前面的城市转移过来,因此有方程:$$dis[v]=max(dis[v],dis[u]+1)$$

    #include<bits/stdc++.h>
    #define N 100010
    #define M 200010
    
    using namespace std;
    
    int n,m,cnt;
    int deg[N],head[N],dis[N];
    
    struct node {
    	int nxt,to;
    }edge[M];
    
    void addEdge(int u,int v) {
    	edge[++cnt]=(node){head[u],v};
    	head[u]=cnt;
    	deg[v]++;
    	return;
    }
    
    void Read() {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++) {
    		int u,v;
    		scanf("%d%d",&u,&v);
    		addEdge(u,v);
    	}
    	return;
    }
    
    void Init() {
    	for(int i=1;i<=n;i++) {
    		dis[i]=1;
    	}
    	return;
    }
    
    void Topo() {
    	queue <int> q;
    	for(int i=1;i<=n;i++) {
    		if(deg[i]==0) {
    			q.push(i);
    		}
    	}
    	while(!q.empty()) {
    		int x=q.front();
    		q.pop();
    		for(int i=head[x];i;i=edge[i].nxt) {
    			int t=edge[i].to;
    			deg[t]--;
    			if(deg[t]==0) {
    				dis[t]=dis[x]+1;
    				q.push(t);
    			}
    		}
    	}
    	return;
    }
    
    void Print() {
    	for(int i=1;i<=n;i++) {
    		printf("%d
    ",dis[i]);
    	}
    	return;
    }
    
    int main()
    {
    	Read();
    	Init();
    	Topo();
    	Print();
    	return 0;
    }
    
  • 相关阅读:
    xml配置文件使用-读取、转换
    .NET 4.0 缓存
    jQuery分页插件pagination.js 笔记
    Spring源码
    Shell编程(字符串篇)
    Linux DNS 相关
    Shell将命令执行结果写入文件
    Linux安装GCC
    Linux网络安全
    产品经理基础
  • 原文地址:https://www.cnblogs.com/luoshui-tianyi/p/11774295.html
Copyright © 2011-2022 走看看