比赛 20110311 评测结果 EWEEEEEWWEEEEEEEETTE
题目名称 岛屿 最终得分 0
用户昵称 苏轼 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2011-03-11 21:04:17
显示代码纯文本
#include <cstdio>
#include <algorithm>
#include <deque>
using namespace std;
const int MAXN=1000005;

struct Node
{
	int v,w;
	Node *next;
	Node(int _v,int _w,Node *_next):v(_v),w(_w),next(_next){}
}*adj[MAXN];

inline void addedge(int u,int v,int w)
{
	adj[u]=new Node(v,w,adj[u]);
	adj[v]=new Node(u,w,adj[v]);
}

int father[MAXN];
int circle[MAXN],size;
long long d[MAXN];

void getcircle(int u)
{
	size=0;
	while(true)
	{
		circle[size++]=u;
		u=father[u];
		if (u==-1)
			break;
	}
}

bool vis[MAXN];
bool dfs(int u)
{
	vis[u]=true;
	bool flag=false;
	for(Node *p=adj[u];p;p=p->next)
		if (!vis[p->v])
		{
			father[p->v]=u;
			if (dfs(p->v))
				return true;
		}
		else if (p->v==father[u])
		{			
			if (!flag) flag=true;
			else 
			{
				getcircle(u);
				return true;
			}
		}
		else 
		{
			getcircle(u);
			return true;
		}
	return false;
}

int dfs2(int u,int father)
{
	vis[u]=true;
	int ans=0;
	for(Node *p=adj[u];p;p=p->next)
		if (p->v!=father)
			ans=max(ans,dfs2(p->v,u)+p->w);
	return ans;
}

long long re;
int N;
long long depth[MAXN],sum[MAXN];
int main()
{
	freopen("isl.in","r",stdin);
	freopen("isl.out","w",stdout);
	scanf("%d",&N);
	for(int i=0;i<N;i++)
	{
		int u,w;
		scanf("%d%d",&u,&w);
		u--;
		addedge(i,u,w);
	}
	deque<int> q;
	for(int i=0;i<N;i++)
		if (!vis[i])
		{
			father[i]=-1;
			if (dfs(i))
			{
				int u1=1%size,u2=size-1;
				for(int j=0;j<size;j++)
				{
					for(Node *p=adj[circle[j]];p;p=p->next)
						if (p->v!=circle[u1] && p->v!=circle[u2])
							depth[circle[j]]=dfs2(circle[j],p->v);
				}
			}
			sum[0]=0;
			for(int i=1;i<size;i++)
				for(Node *p=adj[circle[i]];p;p=p->next)
					if (circle[i-1]==p->v)
					{
						sum[i]=sum[i-1]+p->w;
						break;
					}
			for(int i=size;i<size*2;i++)
				sum[i]=sum[i-1]+sum[i+1-size]-sum[i-size];
			d[0]=0;
			q.push_back(0);
			long long ans=0;
			for(int j=1;j<size*2;j++)
			{
				while(q.size() && q.front()<j-size+1) q.pop_front();
				int k=q.front();
				d[j]=d[k]-sum[k]+sum[j]+depth[j];
				while(q.size() && d[q.back()]-sum[q.back()]<d[j]-sum[j]) q.pop_back();
				q.push_back(j);
				if (d[j]>ans)
					ans=d[j];
			}
			re+=ans;
		}
	printf("%lld\n",re);
	return 0;
}