思路:
用网络流跑二分图的最大匹配,先将H公司第个人的编号变为,然后表示公司和公司的两个人有关系,待匹配。残余网络中非匹配边为从左部到右部的有向边,的边权为,匹配边为从右部到左部的有向边,边权为
非匹配边:表示边的容量
匹配边:
因为要求不可行的边的数量,即不是可行边和必须边的边;先跑一遍最大匹配
最大匹配时,必须边一定会被包括,所以如果,那么它就不是必须边,如果边上的点又不在一个强连通分量内,那么也不是可行边,而是不可行边。

MyCode:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e4+7,maxm=2e5+4e4+7;

int head[maxn],Next[maxm],to[maxm],edge[maxm],tot=1,d[maxn],s,t,now[maxn];
queue<int>q;
void add(int x,int y,int z) {
    to[++tot]=y; Next[tot]=head[x]; head[x]=tot; edge[tot]=z;
    to[++tot]=x; Next[tot]=head[y]; head[y]=tot; edge[tot]=0;
} 
bool bfs() {
    memset(d,0,sizeof d);
    while(q.size()) q.pop();
    q.push(s); d[s]=1; now[s]=head[s];
    while(q.size()) {
        int x=q.front(); q.pop();
        for(int i=head[x],y;i;i=Next[i]) {
            if(edge[i] && !d[y=to[i]]) {
                q.push(y);
                now[y]=head[y];
                d[y]=d[x]+1;
                if(y==t) return 1;
            }
        }
    }
    return 0;
}
int dinic(int x,int flow) {
    if(x==t) return flow;
    int rest=flow,k,i,y;
    for(i=now[x];i && rest; i=Next[i]) {
        if(edge[i] && d[y=to[i]] == d[x] + 1) {
            k=dinic(y,min(rest,edge[i]));
            if(!k) d[y]=0;
            edge[i]-=k; edge[i^1]+=k;
            rest-=k;
        }
    }
    now[x]=i;
    return flow - rest;
}
int dfn[maxn],low[maxn],ins[maxn],c[maxn],stk[maxn],a[maxm],b[maxm],num,cnt,top;
vector<int>ans;
void tarjan(int x,int in_edge) {
    dfn[x]=low[x]=++num;
    stk[++top]=x; ins[x]=1;
    for(int i=head[x],y;i;i=Next[i]) {
        if(!edge[i]) continue;
        if(!dfn[y=to[i]]) {
            tarjan(y,i);
            low[x]=min(low[x],low[y]);
        }
        else if(ins[y])
            low[x]=min(low[x],dfn[y]);
    }
    if(dfn[x]==low[x]) {
        ++cnt; int y;
        do{
            y=stk[top--]; ins[y]=0;
            c[y]=cnt;
        }while(x!=y);
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m,T;
    cin>>n>>m>>T;
    for(int i=1,x,y;i<=T;++i) {
        cin>>x>>y; y+=n;
        a[i]=x; b[i]=y; add(x,y,1);
    }
    s=0,t=n+m+1;
    for(int i=1;i<=n;++i) add(s,i,1);
    for(int i=n+1;i<=m+n;++i) add(i,t,1);
    while(bfs())
        while(dinic(s,0x3f3f3f3f));
    for(int i=0;i<=n+m+1;++i) if(!dfn[i])
        tarjan(i,0);
    for(int i=1;i<=T;++i) if(edge[i<<1] && c[a[i]]!=c[b[i]])
        ans.emplace_back(i);
    cout<<ans.size()<<'\n';
    for(int i:ans) cout<<i<<' ';
    cout<<'\n';
    return 0;
}