HDU 4514

真是神奇,G++TLE,C++500MS。。。

判环有一个图论知识就是,m>=n时必有环。如果以m的范围建图,会MLE。

然后,利用拓扑排序再来判定是否有环,因为有些景点可能是孤立的。同时,在拓扑时就可以DP求最长路了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL __int64

using namespace std;

struct Edge{
	int u,v,c;
	int next;
}edge[200005];
bool vis[100005];
int head[100005];
int deg[100005],tot,cnt;
int stack[100005],st;
int dp[100005];
int ans;

void addedge(int u,int v,int c){
	edge[tot].u=u;
	edge[tot].v=v;
	edge[tot].c=c;
	edge[tot].next=head[u];
	head[u]=tot++;
}

void slove(){
	int u,v;
	while(st>0){
		u=stack[--st];
		vis[u]=true;
		cnt++;
		for(int e=head[u];e!=-1;e=edge[e].next){
			v=edge[e].v;
			if(!vis[v]){
				ans=max(ans,dp[v]+dp[u]+edge[e].c);
				dp[v]=max(dp[v],dp[u]+edge[e].c);
				deg[v]--;
				if(deg[v]==1)
				stack[st++]=v;
			}
		}
	}
}

int main(){
	int n,m,u,v,c;
	while(scanf("%d%d",&n,&m)!=EOF){
		tot=st=cnt=0;
		ans=0;
		for(int i=1;i<=n;i++){
			head[i]=-1; vis[i]=false;
			deg[i]=dp[i]=0;
		}
		if(m>=n){
			for(int i=0;i<m;i++)
			scanf("%d%d%d",&u,&v,&c);
			printf("YES
");
			continue;
		}
		for(int i=0;i<m;i++){
			scanf("%d%d%d",&u,&v,&c);
			addedge(u,v,c);
			addedge(v,u,c);
			deg[u]++;
			deg[v]++;
		}
		for(int i=1;i<=n;i++){
			if(deg[i]==0) cnt++;
			else if(deg[i]==1){
				stack[st++]=i;
			//	vis[i]=true;
			}
		}
		slove();
		if(cnt!=n)
		printf("YES
");
		else printf("%d
",ans);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/jie-dcai/p/4368246.html