这道题是最大流的裸题,但是数据很大,时间卡得比较严,前几次是用Dinic的,都超时了,后面改用效率更高的ISAP,3700MS AC。
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=1e5+100;
const int inf=0x3f3f3f3f;
int head[maxn],cur[maxn],cnt;
int pre[maxn],gap[maxn];
bool vis[maxn];
int N,M;
struct Edge
{
int from,to,cap,next;
}e[10*maxn];
struct ISAP
{
int s,t,dis[maxn];
bool bfs()
{
for(int i=0;i<=N;++i) vis[i]=0; //不要用memset,下同。用memset超10000MS,不用memset AC 3700MS
queue<int> Q;
Q.push(t);
dis[t]=0; vis[t]=1; //记得是dis[t]=0,不是dis[s]=0,因为这个WA了好久
while(!Q.empty())
{
int fro=Q.front(); Q.pop();
for(int i=head[fro]; i ; i=e[i].next)
{
Edge& ed=e[i^1];
if(!vis[ed.from])
{
vis[ed.from]=1;
dis[ed.from]=dis[fro]+1;
Q.push(ed.from);
}
}
}
return vis[s];
}
int augment()
{
int u=t,minflow=inf;
while(u!=s)
{
minflow=min(minflow,e[pre[u]].cap);
u=e[pre[u]].from;
}
u=t;
while(u!=s)
{
e[pre[u]].cap-=minflow;
e[pre[u]^1].cap+=minflow;
u=e[pre[u]].from;
}
return minflow;
}
int max_flow()
{
int flow=0;
for(int i=0;i<=N;++i) cur[i]=head[i],gap[i]=0;
bfs();
for(int i=0;i<=N;++i) gap[dis[i]]++;
int u=s;
while(dis[s]<N)
{
if(u==t)
{
flow+=augment();
u=s;
}
bool flag=0;
for(int i=cur[u]; i ;i=e[i].next)
{
if(e[i].cap&&dis[u]==dis[e[i].to]+1)
{
flag=1;
pre[e[i].to]=i;
cur[u]=i;
u=e[i].to;
break;
}
}
if(!flag)
{
int m=N-1;
for(int i=head[u]; i ;i=e[i].next)
{
if(e[i].cap)
m=min(m,dis[e[i].to]);
}
if(--gap[dis[u]]==0) break;
gap[dis[u]=m+1]++;
cur[u]=head[u];
if(u!=s) u=e[pre[u]].from;
}
}
return flow;
}
}isap;
void addedge(int u,int v,int w)
{
e[cnt].from=u; e[cnt].to=v; e[cnt].cap=w; e[cnt].next=head[u]; head[u]=cnt++;
e[cnt].from=v; e[cnt].to=u; e[cnt].cap=w; e[cnt].next=head[v]; head[v]=cnt++;
}
void init()
{
mem(head,0);
int we=1,ea=1,mi,ma;
for(int i=1;i<=N;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(i==1)
mi=ma=a;
else
{
if(a<mi)
{
mi=a;
we=i;
}
else if(a>ma)
{
ma=a;
ea=i;
}
}
}
cnt=2; isap.s=we; isap.t=ea;
for(int i=1;i<=M;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&M);
init();
printf("%d\n",isap.max_flow());
}
return 0;
}