bzoj2229: [Zjoi2011]最小割(最小割树)
这题是用最小割树做的(不明白最小割树是什么的可以去看看这一题->这里)
有了最小割树就很简单了……点数那么少……每次跑出一个最大流就暴力搞一遍就好了
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<queue> 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 10 char buf[1<<21],*p1=buf,*p2=buf; 11 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;} 12 inline int read(){ 13 #define num ch-'0' 14 char ch;bool flag=0;int res; 15 while(!isdigit(ch=getc())) 16 (ch=='-')&&(flag=true); 17 for(res=num;isdigit(ch=getc());res=res*10+num); 18 (flag)&&(res=-res); 19 #undef num 20 return res; 21 } 22 char sr[1<<21],z[20];int C=-1,Z; 23 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 24 inline void print(int x){ 25 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 26 while(z[++Z]=x%10+48,x/=10); 27 while(sr[++C]=z[Z],--Z);sr[++C]='\n'; 28 } 29 const int N=205,M=10005; 30 int head[N],Next[M],ver[M],edge[M],ee[M],tot=1; 31 queue<int> q; 32 inline void add(int u,int v,int e){ 33 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e,ee[tot]=e; 34 ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=e,ee[tot]=e; 35 } 36 int cur[N],dep[N],n,m,S,T; 37 bool bfs(){ 38 memset(dep,-1,sizeof(dep)); 39 for(int i=1;i<=n;++i) cur[i]=head[i]; 40 while(!q.empty()) q.pop(); 41 q.push(S),dep[S]=0; 42 while(!q.empty()){ 43 int u=q.front();q.pop(); 44 for(int i=head[u];i;i=Next[i]) 45 if(dep[ver[i]]<0&&edge[i]){ 46 q.push(ver[i]),dep[ver[i]]=dep[u]+1; 47 if(ver[i]==T) return true; 48 } 49 } 50 return false; 51 } 52 int dfs(int u,int limit){ 53 if(u==T||!limit) return limit; 54 int flow=0,f; 55 for(int i=cur[u];i;cur[u]=i=Next[i]){ 56 int v=ver[i]; 57 if(dep[v]==dep[u]+1&&(f=dfs(v,min(limit,edge[i])))){ 58 flow+=f,limit-=f; 59 edge[i]-=f,edge[i^1]+=f; 60 if(!limit) break; 61 } 62 } 63 if(!flow) dep[u]=-1; 64 return flow; 65 } 66 int dinic(){ 67 int flow=0; 68 while(bfs()) flow+=dfs(S,inf); 69 return flow; 70 } 71 int id[N],tmp[N],ans[N][N]; 72 void solve(int L,int R){ 73 if(L==R) return; 74 for(int i=2;i<=tot;i+=2) edge[i]=edge[i^1]=ee[i]; 75 S=id[L],T=id[R]; 76 int flow=dinic(); 77 for(int i=1;i<=n;++i) 78 if(~dep[i]) 79 for(int j=1;j<=n;++j) 80 if(dep[j]<0) 81 cmin(ans[i][j],flow),cmin(ans[j][i],flow); 82 int l=L,r=R; 83 for(int i=L;i<=R;++i) 84 if(~dep[id[i]]) tmp[l++]=id[i]; 85 else tmp[r--]=id[i]; 86 memcpy(id+L,tmp+L,sizeof(int)*(R-L+1)); 87 solve(L,l-1),solve(r+1,R); 88 } 89 inline void init(){ 90 memset(head,0,sizeof(head)),tot=1,memset(ans,0x3f,sizeof(ans)); 91 } 92 int main(){ 93 //freopen("testdata.in","r",stdin); 94 int T=read(); 95 while(T--){ 96 init(); 97 n=read(),m=read(); 98 for(int i=1;i<=m;++i){ 99 int u=read(),v=read(),e=read();add(u,v,e); 100 } 101 for(int i=1;i<=n;++i) id[i]=i; 102 solve(1,n); 103 int q=read(); 104 while(q--){ 105 int k=read(),res=0; 106 for(int i=1;i<=n;++i) 107 for(int j=i+1;j<=n;++j) 108 if(ans[i][j]<=k) ++res; 109 print(res); 110 } 111 sr[++C]='\n'; 112 } 113 Ot(); 114 return 0; 115 }
深深地明白自己的弱小