嗯……这题是一个网络流。
加入的边为u,v长度L
则所有长度大于L的边不能使得u,v连通
求个最小割即可。小于同理
两次最小割结果相加。
#include<bits/stdc++.h> #define N 200005 #define M 1000005 #define inf 1000000007 using namespace std; int tu,tv,tval,n,m,cnt,ans,tot=0,head[N],s,t; struct Edge1{int u,v,w;}T[N]; struct Edge2{int u,v,f,next;}G[M]; inline void addedge(int u,int v,int f){ G[tot].u=u;G[tot].v=v;G[tot].f=f;G[tot].next=head[u];head[u]=tot++; G[tot].u=v;G[tot].v=u;G[tot].f=f;G[tot].next=head[v];head[v]=tot++; } inline bool operator<(Edge1 a,Edge1 b){return a.w<b.w;} int level[N]; bool bfs(int s,int t){ memset(level,0,sizeof(level));queue<int>q; q.push(s);level[s]=1; while(!q.empty()){ int u=q.front();q.pop(); if(u==t)return 1; for(int i=head[u];~i;i=G[i].next){ int v=G[i].v,f=G[i].f; if(f&&!level[v])level[v]=level[u]+1,q.push(v); } } return 0; } int dfs(int u,int maxf,int t){ if(u==t)return maxf;int rat=0; for(int i=head[u];~i;i=G[i].next){ int v=G[i].v,f=G[i].f; if(f&&level[v]==level[u]+1){ f=dfs(v,min(maxf-rat,f),t); rat+=f;G[i].f-=f;G[i^1].f+=f; } } if(!rat)level[u]=inf; return rat; } inline int dinic(int s,int t){ int ans=0; while(bfs(s,t))ans+=dfs(s,inf,t); return ans; } inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } int main(){ memset(head,-1,sizeof(head));tot=0; n=read();m=read(); for(int i=1;i<=m;i++)T[i].u=read(),T[i].v=read(),T[i].w=read(); tu=read();tv=read();tval=read(); sort(T+1,T+m+1); for(int i=1;i<=m;i++) if(T[i].w<tval)addedge(T[i].u,T[i].v,1);else break; ans+=dinic(tu,tv); memset(head,-1,sizeof(head));tot=0; for(int i=m;i;i--)if(T[i].w>tval)addedge(T[i].u,T[i].v,1);else break; ans+=dinic(tu,tv); printf("%d ",ans); }