codeforces 645 D Robot Rapping Results Report 【树形dp】

链接:http://codeforces.com/problemset/problem/645/D

题意:给你n个人,和m条关系(有传递性),输入a b代表a比b的等级大,问你最少用到前多少条关系可以确定唯一的关系顺序。不能输出-1。

分析:题意说了不会有两个在同一等级,所以不存在环,且入度为零的点不唯一输出-1。由于不存在环,所以我们可以在图中找到最长链(一定唯一,包含所有节点),在找最长链时,更新当前结点链上的长度和所连的边的编号。最后在最长链上找出最大的边的编号。

代码:

#include <algorithm>
#include <iostream>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <set>
#include <map>
#include <ctime>
#define INF 0x3f3f3f3f
#define Mn 100005
#define Mm 200010
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul (u<<1)
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
struct edge{
	int v,next;
}e[Mm];
int head[Mn],tot;
void addedge(int u,int v) {
	e[tot].v=v;
	e[tot].next=head[u];
	head[u]=tot++;
}
int siz[Mn],son[Mn];
void dfs(int u) {
	if(siz[u]) return ;
	siz[u]=1;
	for(int i=head[u];~i;i=e[i].next) {
		int v=e[i].v;
		dfs(v);
		if(siz[v]>=siz[u]) siz[u]=siz[v]+1,son[u]=i;
	}
}
void init() {
	tot=0;
	CLR(head,-1);
}
int degree[Mn];
int main(){
    int n,m;
	cin>>n>>m;
	init();
	for(int i=1;i<=m;i++) {
		int u,v;
		scanf("%d%d",&u,&v);
		addedge(u,v);
		degree[v]=1;
	}
	int num=0,st=0;
	for(int i=1;i<=n;i++) {
		if(degree[i]==0) {
			num++;
			st=i;
			if(num>1) break;
		}
	}
	if(num==1) {
		dfs(st);
		if(siz[st]<n) {
			cout<<-1<<endl;
		} else {
			int maxx=0;
			for(int i=1;i<=n;i++) {
				maxx=max(maxx,son[i]);
			}
			cout<<maxx+1<<endl;
		}
	}else {
		cout<<-1<<endl;
	}
	return 0;
}


你可能感兴趣的:(codeforces 645 D Robot Rapping Results Report 【树形dp】)