• HDU2647(拓扑排序+反向建图)


    题意不说了,说下思路。

    给出的关系是a要求的工资要比b的工资多,因为尽可能的让老板少付钱,那么a的工资就是b的工资+1。能够确定关系为a>b,依据拓扑排序建边的原则是把“小于”关系看成有向边。那么我们能够建边v->u。

    #include <stdio.h>
    #include <string.h>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <math.h>
    #include <map>
    #include <queue>
    #include <stack>
    #include <set>
    #define M 10000+5
    #define LL long long
    #define Ld __int64
    #define eps 0.00001
    #define INF 999999999
    #define MOD 112233
    #define MAX 26
    #define PI acos(-1.0)
    using namespace std;
    
    vector<int> G[M];
    int num[M];
    int n;
    int into[M],ans;
    
    int toposort()
    {
    	queue<int> q;
    	int cnt=0;
    	ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		if(into[i]==0)						//入度为0的点进入队列中
    			q.push(i);
    	}
    	while(!q.empty())
    	{
    		cnt++;
    		int u=q.front();
    		ans+=num[u];
    		q.pop();
    		for(int i=0;i<G[u].size();i++)
    		{
    			int v=G[u][i];
    			if(--into[v]==0)				//若删除(u,v)这条边之后,v的入度也为0,则压入队列中
    			{
    				q.push(v);				
    				num[v]=num[u]+1;			//v要求的工资比u高
    			}
    		}
    	}
    	if(cnt!=n)					//推断有无环。-1表示有环。1表示无环
    		ans=-1;
    	return ans;
    }
    
    int main()
    {
    	int m;
    	while(~scanf("%d%d",&n,&m))
    	{
    		for(int i=0;i<=n;i++)
    		{
    			G[i].clear();
    			into[i]=0;
    			num[i]=888;
    		}
    		while(m--)
    		{
    			int u,v;
    			scanf("%d%d",&u,&v);
    			G[v].push_back(u);
    			into[u]++;
    		}
    		printf("%d
    ",toposort());
    	}
    	return 0;
    }
    
    
    /*
    
    5 4
    2 1
    2 5
    5 3
    3 4
    
    
    */
    


  • 相关阅读:
    #公式与实现# Jacobi迭代 Gauss-Seidel迭代
    数据结构-C:二叉树的遍历
    c++
    Unix Systems Programming
    二进制文件读取写入(一)
    关于理论、模型与算法
    《计算机图形学与几何造型导论》读书笔记1
    petaPar培训文档
    等参元的高斯积分详解
    水平集函数具体实现
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5085192.html
Copyright © 2020-2023  润新知