这题表面上看上去有些无从下手。。但只需去掉所给边为最大(小)的环就可以了
然后要挑出比所给边大(小)的边建图找最小割即可
要把最大和最小生成树分开做(一开始想一起合着做但这图明显不对呀)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(int i=l;i<=r;i++) 3 #define dec(i,l,r) for(int i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define nm 800000+5 10 #define NM 20000+5 11 using namespace std; 12 int read(){ 13 int x=0,f=1;char ch=getchar(); 14 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 15 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 16 return x*f; 17 } 18 struct edge{ 19 int t,v; 20 edge *next,*rev; 21 }e[nm],*h[NM],*p=e; 22 void _add(int x,int y,int v){ 23 p->t=y;p->v=v;p->next=h[x];h[x]=p;p++; 24 } 25 void add(int x,int y,int v){ 26 _add(x,y,v);_add(y,x,0); 27 h[x]->rev=h[y];h[y]->rev=h[x]; 28 } 29 int n,m,S,T,_t,l[nm],r[nm],dis[nm],d[NM],k,ans; 30 bool v[NM]; 31 queue<int >q; 32 int bfs(){ 33 mem(v);mem(d); 34 v[S]++;d[S]++;q.push(S); 35 while(!q.empty()){ 36 int t=q.front();q.pop(); 37 link(t) 38 if(j->v&&(!d[j->t]||d[j->t]>d[t]+1)){ 39 d[j->t]=d[t]+1; 40 if(!v[j->t])v[j->t]++,q.push(j->t); 41 } 42 } 43 return d[T]; 44 } 45 int dfs(int x,int k){ 46 int _a; 47 if(x==T)return k; 48 link(x) 49 if(j->v&&d[j->t]==d[x]+1&&(_a=dfs(j->t,min(j->v,k)))){ 50 j->v-=_a;j->rev->v+=_a;return _a; 51 } 52 return 0; 53 } 54 int main(){ 55 // freopen("data.in","r",stdin); 56 n=read();m=read(); 57 inc(i,1,m){ 58 l[i]=read();r[i]=read();dis[i]=read(); 59 } 60 S=read();T=read();k=read(); 61 inc(i,1,m) 62 if(dis[i]>k)add(l[i],r[i],1),add(r[i],l[i],1); 63 while(bfs()) 64 if(_t=dfs(S,inf))ans+=_t; 65 p=e;mem(h); 66 inc(i,1,m) 67 if(dis[i]<k)add(l[i],r[i],1),add(r[i],l[i],1); 68 while(bfs()) 69 if(_t=dfs(S,inf))ans+=_t; 70 printf("%d ",ans); 71 return 0; 72 }