Stage 1
树链最小覆盖&其最长链最小解。。
早在看[SHOI]公交线路时就应该做这题的。。。(当时题解没有好像????)
各种错。注意这是POI的题目
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Lson (x<<1) #define Rson ((x<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define MAXN (100000+10) #define MAXM (200000+10) long long mul(long long a,long long b){return (a*b)%F;} long long add(long long a,long long b){return (a+b)%F;} long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;} typedef long long ll; int edge[MAXM],next[MAXM]={0},pre[MAXN]={0},size=1; void addedge(int u,int v) { edge[++size]=v; next[size]=pre[u]; pre[u]=size; } void addedge2(int u,int v){addedge(u,v),addedge(v,u);} int n,fa[MAXN]={0},f[MAXN]={0},son[MAXN]={0},g[MAXN]={0},maxg; void dfs1(int x) { f[x]=x!=1; Forp(x) { int &v=edge[p]; if (v^fa[x]) { fa[v]=x; dfs1(v); f[x]+=f[v];son[x]++; } } f[x]-=(son[x]+(x!=1))/2; } int a[MAXN]={0},tot=0; bool check(int m) { int l=1,r=tot; while (l<=r) { if (l==m) l++; if (r==m) r--; if (a[l]+a[r]>maxg) return 0; l++,r--; } return 1; } bool dfs2(int x) { Forp(x) { int &v=edge[p]; if (v!=fa[x]) if (!dfs2(v)) return 0; } tot=0; Forp(x) //把a独立开,以免混淆 { int &v=edge[p]; if (v!=fa[x]) a[++tot]=g[v]; } // if (tot==0) return (g[x]=1)<=maxg; if (x==1&&tot%2==0) { g[x]=0; // if (tot&1) a[++tot]=0; sort(a+1,a+1+tot); int l=1,r=tot; while (l<r) g[x]=max(g[x],a[l++]+a[r--]) ; if (g[x]>maxg) return 0; return 1; } if (tot%2==0) a[++tot]=0; sort(a+1,a+1+tot); { int l=1,r=tot,ans=INF; while (l<=r) { int m=l+r>>1; if (check(m)) ans=m,r=m-1; else l=m+1; } if (ans^INF) g[x]=a[ans]+(x!=1); else g[x]=INF; } return g[x]<=maxg; } int main() { // freopen("bzoj2067.in","r",stdin); scanf("%d",&n); For(i,n-1){int u,v;scanf("%d%d",&u,&v);addedge2(u,v);} dfs1(1); printf("%d ",f[1]); // For(i,n) cout<<son[i]<<' ';cout<<endl; // For(i,n) cout<<fa[i]<<' ';cout<<endl; // For(i,n) cout<<f[i]<<' ';cout<<endl; //cout<<dfs2(6); { int l=1,r=n-1,ans=0; while (l<=r) { int &m=maxg=(l+r)>>1; if (dfs2(1)) ans=m,r=m-1; else l=m+1; } printf("%d\n",ans); } return 0; }
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Lson (x<<1) #define Rson ((x<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define MAXN (10000+10) long long mul(long long a,long long b){return (a*b)%F;} long long add(long long a,long long b){return (a+b)%F;} long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;} typedef long long ll; int father[MAXN],n; int getfather(int x) { if (father[x]==x) return x; return father[x]=getfather(father[x]); } void union2(int x,int y) { father[getfather(x)]=father[getfather(y)]; } int main() { freopen("bzoj2067_2.in","w",stdout); srand(time(NULL)); n=10;For(i,n) father[i]=i; cout<<n<<endl; For(i,n-1) { int x=rand()%n+1,y=rand()%n+1; while (getfather(x)==getfather(y)) x=rand()%n+1,y=rand()%n+1; cout<<x<<' '<<y<<endl;union2(x,y); } return 0; }