TLE 30pts
我怀疑我学了个假的 dinic,第二组样例本地要跑整整 14 秒。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define MAXN 400010
#define MAXM 1000010
using namespace std;
const int inf=0x3f3f3f3f;
struct Edge
{
int to;
int dis;
int nxt;
}
edge[MAXM<<1];
int head[MAXN],size=1;
void add(int from,int to,int dis)
{
edge[++size].nxt=head[from];
edge[size].to=to;
edge[size].dis=dis;
head[from]=size;
}
void init()
{
memset(head,-1,sizeof(head));
memset(edge,-1,sizeof(edge));
}
int n1,n2,n3,m1,m2,N,s,t;
int u,v;
int ans;
int lv[MAXN];
int now[MAXN];
bool bfs()
{
for(int i=1;i<=N;i++)
lv[i]=inf;
queue<int> q;
q.push(s);
lv[s]=0;
now[s]=head[s];
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];~i;i=edge[i].nxt)
{
int v=edge[i].to;
if(edge[i].dis>0&&lv[v]==inf)
{
lv[v]=lv[x]+1;
now[v]=head[v];
if(v==t)
return 1;
q.push(v);
}
}
}
return 0;
}
int dfs(int x,int val)
{
if(x==t)
return val;
int res=0,k;
for(int i=now[x];~i;i=edge[i].nxt)
{
now[x]=i;
int v=edge[i].to;
if(edge[i].dis>0&&lv[v]==lv[x]+1)
{
k=dfs(v,min(val,edge[i].dis));
if(k==0)
lv[v]=inf;
edge[i].dis-=k;
edge[i^1].dis+=k;
res+=k;
val-=k;
}
}
return res;
}
int main()
{
init();
scanf("%d%d%d",&n1,&n2,&n3);
s=n1+n1+n2+n3+1,t=n1+n1+n2+n3+2,N=n1+n1+n2+n3+2;
for(int i=1;i<=n2;i++)
{
add(s,i,1);
add(i,s,0);
}
scanf("%d",&m1);
for(int i=1;i<=m1;i++)
{
scanf("%d%d",&u,&v);
add(v,n2+u,1);
add(n2+u,v,0);
}
for(int i=1;i<=n1;i++)
{
add(n2+i,n2+n1+i,1);
add(n2+n1+i,n2+i,0);
}
scanf("%d",&m2);
for(int i=1;i<=m2;i++)
{
scanf("%d%d",&u,&v);
add(n2+n1+u,n2+n1+n1+v,1);
add(n2+n1+n1+v,n2+n1+u,0);
}
for(int i=1;i<=n3;i++)
{
add(n2+n1+n1+i,t,1);
add(t,n2+n1+n1+i,0);
}
while(bfs())
ans+=dfs(s,inf);
printf("%d",ans);
return 0;
}