結果
| 問題 |
No.19 ステージの選択
|
| ユーザー |
LayCurse
|
| 提出日時 | 2014-11-07 10:03:09 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 6,192 bytes |
| コンパイル時間 | 1,857 ms |
| コンパイル使用メモリ | 161,608 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-12-23 10:00:43 |
| 合計ジャッジ時間 | 2,419 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 24 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)
#define mygc(c) (c)=getchar_unlocked()
#define mypc(c) putchar_unlocked(c)
#define ll long long
#define ull unsigned ll
void reader(int *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);}
void reader(int *x, int *y){reader(x);reader(y);}
void reader(int *x, int *y, int *z){reader(x);reader(y);reader(z);}
void reader(ll *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);}
int reader(char c[]){int i,s=0;for(;;){mygc(i);if(i!=' '&&i!='\n'&&i!='\r'&&i!='\t'&&i!=EOF) break;}c[s++]=i;for(;;){mygc(i);if(i==' '||i=='\n'||i=='\r'||i=='\t'||i==EOF) break;c[s++]=i;}c[s]='\0';return s;}
void writer(int x, char c){int s=0,m=0;char f[10];if(x<0)m=1,x=-x;while(x)f[s++]=x%10,x/=10;if(!s)f[s++]=0;if(m)mypc('-');while(s--)mypc(f[s]+'0');mypc(c);}
void writer(ll x, char c){int s=0,m=0;char f[20];if(x<0)m=1,x=-x;while(x)f[s++]=x%10,x/=10;if(!s)f[s++]=0;if(m)mypc('-');while(s--)mypc(f[s]+'0');mypc(c);}
void writer(const char c[]){int i;for(i=0;c[i]!='\0';i++)mypc(c[i]);}
void* setDirectEdge(int N, int M, int A[], int B[], int **es, int ***edge, void *workMemory){int i;*es=(int*)workMemory;*edge=(int**)((*es)+N);(*edge)[0]=(int*)((*edge)+N);rep(i,N)(*es)[i]=0;rep(i,M)(*es)[A[i]]++;REP(i,1,N)(*edge)[i]=(*edge)[i-1]+(*es)[i-1];workMemory=(void*)((*edge)[N-1]+(*es)[N-1]);rep(i,N)(*es)[i]=0;rep(i,M)(*edge)[A[i]][(*es)[A[i]]++]=B[i];return workMemory;}
void* setUndirectEdge(int N, int M, int A[], int B[], int **es, int ***edge, void *workMemory){int i;*es=(int*)workMemory;*edge=(int**)((*es)+N);(*edge)[0]=(int*)((*edge)+N);rep(i,N)(*es)[i]=0;rep(i,M)(*es)[A[i]]++,(*es)[B[i]]++;REP(i,1,N)(*edge)[i]=(*edge)[i-1]+(*es)[i-1];workMemory=(void*)((*edge)[N-1]+(*es)[N-1]);rep(i,N)(*es)[i]=0;rep(i,M)(*edge)[A[i]][(*es)[A[i]]++]=B[i],(*edge)[B[i]][(*es)[B[i]]++]=A[i];return workMemory;}
void* getReverseGraph(int N, int *es, int **edge, int **r_es, int ***r_edge, void *workMemory){int i,j,k;*r_es=(int*)workMemory;*r_edge=(int**)((*r_es)+N);(*r_edge)[0]=(int*)((*r_edge)+N);rep(i,N)(*r_es)[i] = 0;rep(i,N)rep(j,es[i])(*r_es)[edge[i][j]]++;REP(i,1,N)(*r_edge)[i]=(*r_edge)[i-1]+(*r_es)[i-1];workMemory=(void*)((*r_edge)[N-1]+(*r_es)[N-1]);rep(i,N)(*r_es)[i]=0;rep(i,N)rep(j,es[i])k=edge[i][j],(*r_edge)[k][(*r_es)[k]++]=i;return workMemory;}
void getDepthOfTreeDFS(int node, int bef, int *depth, int *es, int **edge){int i,k;rep(i,es[node]){k=edge[node][i];if(bef==k)continue;depth[k]=depth[node] + 1;getDepthOfTreeDFS(k, node, depth, es, edge);}}
void* getDepthOfTree(int N, int root, int *es, int **edge, int **depth, void *workMemory){*depth=(int*)workMemory;workMemory=(void*)((*depth)+N);(*depth)[root]=0;getDepthOfTreeDFS(root,-1,*depth,es,edge);return workMemory;}
template<class T> void doublingRMQBuild(T arr[], int n, int res[]){int i,k,h;rep(i,n)res[i]=i;for(k=1;;k++){h=(1<<(k-1));if(h>=n)break;rep(i,n){res[n*k+i]=res[n*(k-1)+i];if(i+h<n&&arr[res[n*k+i]]>arr[res[n*(k-1)+i+h]])res[n*k+i]=res[n*(k-1)+i+h];}}}
template<class T> void* doublingRMQBuild(T arr[], int n, int **res, void *workMemory){int i,k,h;*res=(int*)workMemory;rep(i,n)(*res)[i]=i;for(k=1;;k++){h=(1<<(k-1));if(h>=n)break;rep(i,n){(*res)[n*k+i]=(*res)[n*(k-1)+i];if(i+h<n&&arr[(*res)[n*k+i]]>arr[(*res)[n*(k-1)+i+h]])(*res)[n*k+i]=(*res)[n*(k-1)+i+h];}}return (void*)((*res)+n*k);}
template<class T> int doublingRMQQuery(T arr[], int n, int rmq[], int a, int b){int d,w=b-a+1,A,B;for(d=0;(1<<(d+1))<=w;d++);A=rmq[n*d+a];B=rmq[n*d+b-(1<<d)+1];return arr[A]>arr[B]?B:A;}
struct LCA{
int *depth, *vs, *id, *rmq, N, *es, **edge;
void dfs(int node, int bef, int dep, int *num){int i,k;id[node]=*num;vs[*num]=node;depth[(*num)++]=dep;rep(i,es[node]){k=edge[node][i];if(k==bef)continue;dfs(k,node,dep+1,num);vs[*num]=node;depth[(*num)++]=dep;}}
void* init(int N_, int root, int *es_, int **edge_, void *workMemory){int m=0;N=N_;es=es_;edge=edge_;depth=(int*)workMemory;vs=depth+2*N-1;id=vs+2*N-1;dfs(root,-1,0,&m);return doublingRMQBuild(depth,2*N-1,&rmq,(void*)(id+N));}
int get(int a, int b){return vs[doublingRMQQuery(depth, 2*N-1, rmq, min(id[a],id[b]), max(id[a],id[b]))];}
int getDepth(int a, int b){return depth[doublingRMQQuery(depth,2*N-1,rmq,min(id[a],id[b]),max(id[a],id[b]))];}
};
int StronglyConnectedComponentsDFS(int *es, int **edge, int num[], int st, int mx){
int i,j;
num[st]=-2;
rep(i,es[st]) {
j=edge[st][i]; if(num[j]==-1) mx=StronglyConnectedComponentsDFS(es,edge,num,j,mx);
}
num[st]=mx; return mx+1;
}
int StronglyConnectedComponents(int N, int *es, int **edge, int res[], void *workMemory){
int i, j, k, ret=0;
int *r_es, **r_edge;
int *st, st_size, *num, *nrv;
workMemory = getReverseGraph(N, es, edge, &r_es, &r_edge, workMemory);
st = (int*) workMemory; num = st+N; nrv = num + N;
rep(i,N) res[i] = num[i] = -1;
k = 0;
rep(i,N) if(num[i]==-1) k = StronglyConnectedComponentsDFS(es,edge,num,i,k);
rep(i,N) nrv[num[i]] = i;
for(k=N-1;k>=0;k--) {
i=nrv[k]; if(res[i]>=0)continue;
res[i]=ret; st_size=0; st[st_size++]=i;
while(st_size){
i=st[--st_size];
rep(j,r_es[i])
if(res[r_edge[i][j]]==-1) res[r_edge[i][j]]=ret, st[st_size++]=r_edge[i][j];
}
ret++;
}
return ret;
}
int N;
int A[222], B[222], L[222];
int com[222], deg[222], mn[222];
int main(){
int i, j, k, nn;
int res;
int *es, **edge;
void *mem = malloc(10000000);
reader(&N);
rep(i,N) reader(L+i,A+i), A[i]--, B[i]=i;
mem = setDirectEdge(N, N, A, B, &es, &edge, mem);
nn = StronglyConnectedComponents(N, es, edge, com, mem);
res = 0;
rep(i,N) res += L[i];
rep(i,N) if(com[A[i]] != com[B[i]]) deg[com[B[i]]]++;
rep(i,nn) mn[i] = 10000;
rep(i,N) mn[com[i]] = min(mn[com[i]], L[i]);
rep(i,nn) if(!deg[i]) res += mn[i];
printf("%.1f\n",res/2.0);
return 0;
}
LayCurse