标签:return ons spfa empty std lin 完全 i++ name
看到数据范围,考虑网络流..但考的时候完全不知道怎么建图
考虑流量表示选的点个数,费用表示选点的收益,跑最大费用最大流
那么我用一个点x表示某树中的询问点x,刨去它子孙询问点的子树后的子树
对于树1,连边S->x,流量为x的限定数-孩子询问的限定数,费用为0
对于树2,连边x->T,流量为x的限定数-孩子询问的限定数,费用为0
以限制数量
之后对于每个点,给它在树1中最近的询问祖先到树2中最近的询问祖先 连边,流量为1,费用为点权
表示选这个点
如果S的出流量和不等于T的入流量和,或者最后没跑满,则说明无解
1 #include<bits/stdc++.h> 2 #define CLR(a,x) memset(a,x,sizeof(a)) 3 #define MP make_pair 4 using namespace std; 5 typedef long long ll; 6 typedef unsigned long long ull; 7 typedef pair<int,int> pa; 8 const int maxn=505; 9 10 inline ll rd(){ 11 ll x=0;char c=getchar();int neg=1; 12 while(c<‘0‘||c>‘9‘){if(c==‘-‘) neg=-1;c=getchar();} 13 while(c>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘,c=getchar(); 14 return x*neg; 15 } 16 17 int teg[2][maxn*2][2],tegh[2][maxn],tect[2]; 18 int dem[2][maxn],cfa[2][maxn],rt[2]; 19 inline void adteg(int o,int a,int b){ 20 teg[o][++tect[o]][0]=b,teg[o][tect[o]][1]=tegh[o][a],tegh[o][a]=tect[o]; 21 teg[o][++tect[o]][0]=a,teg[o][tect[o]][1]=tegh[o][b],tegh[o][b]=tect[o]; 22 } 23 struct Edge{ 24 int b,l,c,ne; 25 }eg[maxn*6]; 26 int N,egh[maxn*2],ect=1,S=1004,T=1005; 27 int val[maxn],inl,outl; 28 29 inline void ext(){ 30 printf("-1\n"); 31 exit(0); 32 } 33 34 inline void adeg(int a,int b,int l,int c){ 35 if(a==S) inl+=l; 36 if(b==T) outl+=l; 37 eg[++ect]=(Edge){b,l,c,egh[a]},egh[a]=ect; 38 eg[++ect]=(Edge){a,0,-c,egh[b]},egh[b]=ect; 39 } 40 inline int dfs(int o,int x,int f,int cl){ 41 if(dem[o][x]) cl=x; 42 cfa[o][x]=cl; 43 int n=0; 44 for(int i=tegh[o][x];i;i=teg[o][i][1]){ 45 int b=teg[o][i][0];if(b==f) continue; 46 n+=dfs(o,b,x,cl); 47 } 48 if(dem[o][x]){ 49 if(dem[o][x]<n) ext(); 50 if(o==0) adeg(S,x,dem[o][x]-n,0); 51 else adeg(x+N,T,dem[o][x]-n,0); 52 return dem[o][x]; 53 }return n; 54 } 55 56 queue<int> q; 57 int dis[maxn*2],ine[maxn*2]; 58 bool flag[maxn*2]; 59 60 inline bool spfa(){ 61 CLR(dis,-127);dis[S]=0; 62 CLR(ine,0);q.push(S); 63 while(!q.empty()){ 64 int p=q.front();q.pop(); 65 flag[p]=0; 66 for(int i=egh[p];i;i=eg[i].ne){ 67 int b=eg[i].b;if(!eg[i].l) continue; 68 if(dis[b]<dis[p]+eg[i].c){ 69 dis[b]=dis[p]+eg[i].c,ine[b]=i; 70 if(!flag[b]) q.push(b),flag[b]=1; 71 } 72 } 73 }return dis[T]>=-1e9; 74 } 75 76 int main(){ 77 //freopen("","r",stdin); 78 int i,j,k; 79 N=rd(),rt[0]=rd(),rt[1]=rd(); 80 for(i=1;i<=N;i++) 81 val[i]=rd(); 82 for(i=1;i<N;i++) adteg(0,rd(),rd()); 83 for(i=1;i<N;i++) adteg(1,rd(),rd()); 84 for(i=rd();i;i--){ 85 int x=rd(),y=rd(); 86 dem[0][x]=y; 87 }for(i=rd();i;i--){ 88 int x=rd(),y=rd(); 89 dem[1][x]=y; 90 } 91 dfs(0,rt[0],0,0);dfs(1,rt[1],0,0); 92 for(i=1;i<=N;i++){ 93 adeg(cfa[0][i],cfa[1][i]+N,1,val[i]); 94 } 95 if(inl!=outl) ext(); 96 int ans=0; 97 while(spfa()){ 98 int mi=1e9; 99 for(i=T;i!=S;i=eg[ine[i]^1].b){ 100 mi=min(mi,eg[ine[i]].l); 101 }ans+=mi*dis[T]; 102 inl-=mi; 103 for(i=T;i!=S;i=eg[ine[i]^1].b){ 104 eg[ine[i]].l-=mi,eg[ine[i]^1].l+=mi; 105 } 106 } 107 if(inl) ext(); 108 printf("%d\n",ans); 109 return 0; 110 }
标签:return ons spfa empty std lin 完全 i++ name
原文地址:https://www.cnblogs.com/Ressed/p/10050708.html