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;
    }
    
  • 相关阅读:
    hdu 2819 Swap
    匈牙利算法
    hdu 1281 棋盘游戏
    hdu 2444 The Accomodation of Students(最大匹配 + 二分图判断)
    hdu 1045 Fire Net(最小覆盖点+构图(缩点))
    Python实现时钟
    挥之不去的DDOS
    随机数
    wchar_t的用法
    Visual Studio函数被警告安全,如何修改
  • 原文地址:https://www.cnblogs.com/luoshui-tianyi/p/11774295.html
Copyright © 2011-2022 走看看