标签:
啊好烦这道题。。。。
基本思路网上都有。
注意的一点是在匹配的时候,如果有军队的来源没有被匹配到,那么就先匹配这个来源。(因为不花钱)。
不过数据好水。。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 50050 #define maxe 100500 using namespace std; int n,x,y,z,g[maxv],nume=0,m,c[maxv],anc[maxv][20],dis[maxv][20],l=1,r=0,disr[maxv],kr=0,fath[maxv]; int top=0,cnt=0; bool vis[maxv],ret[maxv]; struct edge { int v,w,nxt; }e[maxe]; struct status { int val,id; }regis[maxv],stack[maxv]; bool cmp(status a,status b) { return a.val<b.val; } void addedge(int u,int v,int w) { e[++nume].v=v; e[nume].w=w; e[nume].nxt=g[u]; g[u]=nume; } void dfs1(int x,int father) { if (father==1) fath[x]=x; else if (x!=1) fath[x]=fath[father]; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=father) { anc[v][0]=x;dis[v][0]=e[i].w; disr[v]=disr[x]+e[i].w;r=max(r,disr[v]); dfs1(v,x); } } } bool dfs2(int x,int father) { if (vis[x]) return true; int cnt1=0,cnt2=0; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=father) { cnt1++; if (dfs2(v,x)) cnt2++; } } if ((cnt1==cnt2) && (cnt1!=0)) return true; return false; } void get_table() { r+=kr; for (int i=1;i<=16;i++) for (int j=1;j<=n;j++) { anc[j][i]=anc[anc[j][i-1]][i-1]; dis[j][i]=dis[j][i-1]+dis[anc[j][i-1]][i-1]; } } int get_pnt(int x,int r) { for (int i=16;i>=0;i--) { if (r>=dis[x][i]) { r-=dis[x][i]; x=anc[x][i]; } } return x; } bool check(int x) { memset(vis,false,sizeof(vis)); memset(ret,false,sizeof(ret)); top=0;cnt=0; for (int i=1;i<=m;i++) { int v=c[i]; if (disr[v]<x) { top++; stack[top].val=x-disr[v]; stack[top].id=fath[v]; } else if (disr[v]==x) vis[fath[v]]=true; else vis[get_pnt(v,x)]=true; } for (int i=g[1];i;i=e[i].nxt) { int v=e[i].v; if (!dfs2(v,1)) { regis[++cnt].val=disr[v]; regis[cnt].id=v; ret[v]=true; } } if (top<cnt) return false; sort(stack+1,stack+top+1,cmp); sort(regis+1,regis+cnt+1,cmp); int p1=1,p2=1; while ((p2<=cnt) && (p1<=top)) { if (ret[stack[p1].id]) {ret[stack[p1].id]=false;p1++;} else { while ((!ret[regis[p2].id]) && (p2<=cnt)) p2++; while ((stack[p1].val<regis[p2].val) && (p1<=top)) p1++; if (p2==cnt+1) break; if (p1==top+1) break; ret[regis[p2].id]=false;p1++;p2++; } } for (int i=g[1];i;i=e[i].nxt) { int v=e[i].v; if (ret[v]) return false; } return true; } int get_ans() { int ans; while (l<=r) { int mid=(l+r)>>1; if (check(mid)) {ans=mid;r=mid-1;} else l=mid+1; } return ans; } int main() { scanf("%d",&n); for (int i=1;i<=n-1;i++) { scanf("%d%d%d",&x,&y,&z); addedge(x,y,z); addedge(y,x,z); if ((x==1) || (y==1)) kr=max(kr,z); } scanf("%d",&m); for (int i=1;i<=m;i++) scanf("%d",&c[i]); dfs1(1,0); get_table(); printf("%d\n",get_ans()); return 0; }
标签:
原文地址:http://www.cnblogs.com/ziliuziliu/p/5744071.html