比赛 |
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();
}