标签:
树上奇奇怪怪的算法真是多...
//POJ 1741 //by Cydiater //2016.8.17 #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <ctime> #include <cmath> #include <cstdlib> #include <iomanip> #include <cstdio> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) const int MAXN=1e5+5; const int oo=0x3f3f3f3f; inline int read(){ char ch=getchar();int x=0,f=1; while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } int N,K,LINK[MAXN],len=0,root,siz[MAXN],dis[MAXN],ms[MAXN],sum,ans,dep[MAXN],q[MAXN],head,tail; bool vis[MAXN]; struct edge{int y,next,v;}e[MAXN]; namespace solution{ inline void insert(int x,int y,int v){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].v=v;} void init(){ if(N==0&&K==0)exit(0); len=0;ans=0; memset(LINK,0,sizeof(LINK)); memset(siz,0,sizeof(siz)); memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); memset(dep,0,sizeof(dep)); memset(ms,0,sizeof(ms)); up(i,1,N-1){ int x=read(),y=read(),v=read(); insert(x,y,v); insert(y,x,v); } } void getroot(int node,int fa){ siz[node]=1;ms[node]=0; for(int i=LINK[node];i;i=e[i].next) if(!vis[e[i].y]&&e[i].y!=fa){ getroot(e[i].y,node); siz[node]+=siz[e[i].y]; ms[node]=max(ms[node],siz[e[i].y]); } ms[node]=max(ms[node],sum-siz[node]); if(ms[node]<ms[root])root=node; } void getdeep(int node,int fa){ q[++tail]=dis[node]; for(int i=LINK[node];i;i=e[i].next) if(!vis[e[i].y]&&e[i].y!=fa){ dis[e[i].y]=dis[node]+e[i].v; getdeep(e[i].y,node); } } int col(int node,int di){ int tmp=0; dis[node]=di;head=1;tail=0; getdeep(node,0); sort(q+1,q+tail+1); while(head<tail){ while(q[head]+q[tail]>K&&head<tail)tail--; tmp+=tail-head; head++; } return tmp; } void work(int node){ ans+=col(node,0); vis[node]=1; for(int i=LINK[node];i;i=e[i].next) if(!vis[e[i].y]){ ans-=col(e[i].y,e[i].v); sum=siz[e[i].y]; root=0; getroot(e[i].y,node); work(root); } } void slove(){ root=0;sum=N;ms[0]=oo; getroot(1,0); work(root); } void output(){ printf("%d\n",ans); } } int main(){ //freopen("input.in","r",stdin); using namespace solution; while(scanf("%d %d",&N,&K)!=EOF){ init(); slove(); output(); } return 0; }
//BZOJ 2152 //by Cydiater //2016.8.17 #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <ctime> #include <cstdio> #include <cstdlib> #include <iomanip> #include <cmath> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) const int MAXN=1e5+5; const int oo=0x3f3f3f3f; inline int read(){ char ch=getchar();int x=0,f=1; while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } int N,LINK[MAXN],len=0,ms[MAXN],siz[MAXN],ans=0,root=0,sum,dis[MAXN],q[MAXN],head,tail,c[5]; bool vis[MAXN]; struct edge{ int y,next,v; }e[MAXN]; namespace solution{ int gcd(int a,int b){return b==0?a:gcd(b,a%b);} inline void insert(int x,int y,int v){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].v=v;} void init(){ N=read(); up(i,1,N-1){ int x=read(),y=read(),v=read(); insert(x,y,v); insert(y,x,v); } } void getroot(int node,int fa){ siz[node]=1;ms[node]=0; for(int i=LINK[node];i;i=e[i].next) if(!vis[e[i].y]&&e[i].y!=fa){ getroot(e[i].y,node); siz[node]+=siz[e[i].y]; ms[node]=max(ms[node],siz[e[i].y]); } ms[node]=max(ms[node],sum-siz[node]); if(ms[node]<ms[root])root=node; } void getdeep(int node,int fa){ c[dis[node]]++; for(int i=LINK[node];i;i=e[i].next) if(!vis[e[i].y]&&e[i].y!=fa){ dis[e[i].y]=(dis[node]+e[i].v)%3; getdeep(e[i].y,node); } } int col(int node,int di){ c[0]=c[1]=c[2]=0; dis[node]=di%3; getdeep(node,0); return c[1]*c[2]*2+c[0]*c[0]; } void work(int node){ ans+=col(node,0); vis[node]=1; for(int i=LINK[node];i;i=e[i].next) if(!vis[e[i].y]){ ans-=col(e[i].y,e[i].v); sum=siz[e[i].y];root=0; getroot(e[i].y,node); work(root); } } void slove(){ memset(vis,0,sizeof(vis)); ms[0]=oo;sum=N; getroot(1,0); work(root); } void output(){ int d=gcd(ans,N*N); printf("%d/%d\n",(ans)/d,N*N/d); } } int main(){ //freopen("input.in","r",stdin); using namespace solution; init(); slove(); output(); return 0; }
标签:
原文地址:http://www.cnblogs.com/Cydiater/p/5792756.html