舞动的夜晚

  • 一般二分图的不可行边
  • 此时(u,v)不一定存在增广路,但即使是存在其他增广路,借助源点和汇点,(u,v)仍然连通,u,v是否同在一个强连通分量的判据仍然成立
#include <bits/stdc++.h>
using namespace std;
int to[300005],e[300005],nx[300005],h[20005],cur[20005],tot=1;
int u[100005],v[100005];
bool ma[20005];
void add(int u,int v,int w)
{
	tot++;
	to[tot]=v;
	e[tot]=w;
	nx[tot]=h[u];
	h[u]=tot;
}
int s,t,flow;
int d[20005];
bool bfs()
{
	queue<int>q;
	memset(d,0,sizeof(int)*(t-s+1));
	q.push(s);
	d[s]=1;
	while(q.size())
	{
		int n1=q.front();
		q.pop();
		cur[n1]=h[n1];
		for(int i=h[n1];i;i=nx[i])
		{
			int y=to[i];
			if(!d[y]&&e[i])
			{
				d[y]=d[n1]+1;
				q.push(y);
			}
		}
	}
	return d[t];
}
int dinic(int n1,int flow)
{
	if(n1==t)
	{
		return flow;
	}
	int rest=flow;
	for(int i=cur[n1];i&&rest;i=nx[i])
	{
		cur[n1]=i;
		int y=to[i];
		if(e[i]&&d[y]==d[n1]+1)
		{
			int k=dinic(y,min(rest,e[i]));
			if(k==0)
			{
				d[y]=0;
			}
			rest-=k;
			e[i]-=k;
			e[i^1]+=k;
		}
	}
	return flow-rest;
}
vector<int>a[500005];
int dfn[500005],low[500005],cnt,id[500005];
bool ins[500005];
stack<int>st;
void tarjan(int n1)
{
	dfn[n1]=low[n1]=++tot;
	st.push(n1);
	ins[n1]=true;
	for(int i=h[n1];i;i=nx[i])
	{
		if(e[i])
		{
			if(!dfn[to[i]])
			{
				tarjan(to[i]);
				low[n1]=min(low[n1],low[to[i]]);
			}
			else if(ins[to[i]]==true)
			{
				low[n1]=min(low[n1],dfn[to[i]]);
			}
		}
	}
	if(dfn[n1]==low[n1])
	{
		cnt++;
		while(st.top()!=n1)
		{
			id[st.top()]=cnt;
			ins[st.top()]=false;
			st.pop();
		}
		id[n1]=cnt;
		ins[n1]=false;
		st.pop();
	}
}
vector<int>ans;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int nl,nr,m;
	cin>>nl>>nr>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>u[i]>>v[i];
		add(u[i],v[i]+nl,1);
		add(v[i]+nl,u[i],0);
	}
	s=0;
	t=nl+nr+1;
	for(int i=1;i<=nl;i++)
	{
		add(s,i,1);
		add(i,s,0);
	}
	for(int i=nl+1;i<=nl+nr;i++)
	{
		add(i,t,1);
		add(t,i,0);
	}
	while(bfs())
	{
		dinic(s,INT_MAX);
	}
	tot=0;
	for(int i=s;i<=t;i++)
	{
		if(!dfn[i])
		{
			tarjan(i);
		}
	}
	for(int i=1;i<=m;i++)
	{
		if(e[i*2+1]==1)
		{
			ma[u[i]]=true;
			ma[v[i]+nl]=true;
		}
	}
	for(int i=1;i<=m;i++)
	{
		if(e[i*2]==1)
		{
			if(ma[u[i]]&&ma[v[i]+nl])
			{
				if(id[u[i]]!=id[v[i]+nl])
				{
					ans.push_back(i);
				}
			}
		}
	}
	cout<<ans.size()<<endl;
	for(int id:ans)
	{
		cout<<id<<" ";
	}
	cout<<endl;
	return 0;
}
posted @ 2025-03-01 21:27  D06  阅读(8)  评论(0)    收藏  举报
//雪花飘落效果