比赛 20110311 评测结果 AAAWWEWWAWAWEWWWWTTA
题目名称 岛屿 最终得分 30
用户昵称 .Xmz 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2011-03-11 21:59:10
显示代码纯文本
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>

using namespace std;

const int maxm=3000001;
const int maxn=1000001;

struct edge
{
	int t,c;
	edge *next,*op;
}E[maxm],*V[maxn];
int eh,n;
inline void addedge(int a,int b,int c)
{
	E[++eh].next=V[a];  V[a]=E+eh;  V[a]->t=b;  V[a]->c=c;
	E[++eh].next=V[b];  V[b]=E+eh;  V[b]->t=a;  V[b]->c=c;
	V[a]->op=V[b];  V[b]->op=V[a];
}

bool y[maxn],iscir[maxn];
long long g[maxn];

void init()
{
	scanf("%d",&n);
	int b,c;
	for (int i=1;i<=n;i++)
	{
		scanf("%d%d",&b,&c);
		addedge(i,b,c);
	}
}

int dfs(int u,edge *la)
{
	y[u]=true;int t=0,re=0;
	for (edge *e=V[u];e;e=e->next)
	if (e->op!=la)
	{
		if (!y[e->t]) t=dfs(e->t,e);
		else t=e->t,iscir[u]=true;re=t;;
		if (t!=0 && e->t!=t) {iscir[u]=true;re=t;}
	}
	return re;
}

void dp(int u,edge *la)
{
	for (edge *e=V[u];e;e=e->next)
	if (e->op!=la && !iscir[e->t])
	{
		dp(e->t,e);
		g[u]=max(g[u],g[e->t]+e->c);
	}
}

int m,k,now;
struct queue
{
	int id[2*maxn];
	long long val[2*maxn];
	int qt,qw;
	void ins(int idd,long long v)
	{
		while (qt<=qw && v>val[qw]) --qw;
		qw++;
		id[qw]=idd;
		val[qw]=v;
	}
	
	long long getj(int lim)
	{
		while (qt<=qw && id[qt]<=lim) qt++;
		return val[qt];
	}
}Q;
int d[2*maxn];
long long sum[2*maxn];
void make(int u,int la,int T)
{
	y[u]=true;
	d[++now]=u;
	for (edge *e=V[u];e;e=e->next)
	if (e->t!=T && e->t!=la && iscir[e->t])
	{
		sum[now+1]=sum[now]+e->c;
		make(e->t,u,T);
		return;
	}
}

long long cul(int u)
{
	Q.qt=0;Q.qw=-1;now=0;
	long long res=0;
	for (edge *e=V[u];e;e=e->next)
	if (iscir[e->t]) sum[1]=e->c;
	make(u,0,u);
	m=2*now;k=now;
	for (int i=now+1;i<=2*now;i++) d[i]=d[i-now],sum[i]=sum[now]+sum[i-now];
	for (int i=1;i<=m;i++)
	{
		if (i>=now) res=max(res,Q.getj(i-now)-(sum[m]-sum[i])+g[d[i]]);
		Q.ins(i,sum[m]-sum[i]+g[d[i]]);
	}
	return res;
}

long long ans;

void solve()
{
	for (int i=1;i<=n;i++) if (!y[i]) dfs(i,NULL);
	//for (int i=1;i<=n;i++) if (iscir[i]) printf("%d\n",i);
	for (int i=1;i<=n;i++) if (iscir[i]) dp(i,NULL);
	for (int i=1;i<=n;i++) y[i]=false;
	for (int i=1;i<=n;i++) 
	if (iscir[i] && !y[i]) ans+=cul(i);
	printf("%lld\n",ans);
}

int main()
{
	freopen("isl.in","r",stdin);
	freopen("isl.out","w",stdout);
	init();
	solve();
}