F. Minimal k-covering+最大流

F. Minimal k-covering
time limit per test
1.5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given a bipartite graph G = (U, V, E), U is the set of vertices of the first part, V is the set of vertices of the second part and E is the set of edges. There might be multiple edges.

Let's call some subset of its edges k-covering iff the graph has each of its vertices incident to at least k edges. Minimal k-covering is such a k-covering that the size of the subset is minimal possible.

Your task is to find minimal k-covering for each , where minDegree is the minimal degree of any vertex in graph G.

Input

The first line contains three integers n1, n2 and m (1 ≤ n1, n2 ≤ 2000, 0 ≤ m ≤ 2000) — the number of vertices in the first part, the number of vertices in the second part and the number of edges, respectively.

The i-th of the next m lines contain two integers ui and vi (1 ≤ ui ≤ n1, 1 ≤ vi ≤ n2) — the description of the i-th edge, ui is the index of the vertex in the first part and vi is the index of the vertex in the second part.

Output

For each print the subset of edges (minimal k-covering) in separate line.

The first integer cntk of the k-th line is the number of edges in minimal k-covering of the graph. Then cntk integers follow — original indices of the edges which belong to the minimal k-covering, these indices should be pairwise distinct. Edges are numbered 1 through m in order they are given in the input.

Examples
Input
Copy
3 3 7
1 2
2 3
1 3
3 2
3 3
2 1
2 1
Output
Copy
0 
3 3 7 4 
6 1 3 6 7 4 5 
Input
Copy
1 1 5
1 1
1 1
1 1
1 1
1 1
Output
Copy
0 
1 5 
2 4 5 
3 3 4 5 
4 2 3 4 5 
5 1 2 3 4 5 

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;

typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;


#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=b-1;i>=a;i--)

#define all(a) (a).begin(),(a).end()
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define f first
#define s second

ll rd(){
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

const int INF=0x3f3f3f3f;

class edge{
public:
    int s,e,f;
    edge(){}
    edge(int s,int e,int f):s(s),e(e),f(f){}
};

vector<edge> Ve;
vi conn[10050];


void epush(int s,int e,int f){
    conn[s].pb(Ve.size());
    conn[e].pb(Ve.size()+1);
    Ve.eb(s,e,f);
    Ve.eb(e,s,0);
}

int in[2050][2];

int dis[10050];
int dchk[10050];
int pos[10050];

int DFS(int n,int snk,int C){
    if(n==snk)return 1;
    dchk[n]=C;
    for(;pos[n]<conn[n].size();pos[n]++){
        int it=conn[n][pos[n]];
        edge &ed=Ve[it];
        if(ed.f==0||dchk[ed.e]==C||dis[ed.e]!=dis[ed.s]+1)continue;
        if(DFS(ed.e,snk,C)){
            Ve[it].f--;
            Ve[it^1].f++;
            return 1;
        }
    }
    return 0;
}

int getFlow(int src,int snk){
    int i,j;
    vi Vu;
    rep(i,0,snk)
    dis[i]=INF,dchk[i]=0,pos[i]=0;
    dis[src]=0;
    Vu.pb(src);
    for(i=0;i<Vu.size();i++){
        for(auto it:conn[Vu[i]]){
            edge &ed=Ve[it];
            if(ed.f==0||dis[Ve[it].e]!=INF)continue;
            dis[Ve[it].e]=dis[Ve[it].s]+1;
            Vu.pb(Ve[it].e);
        }
    }
    if(dis[snk]==INF)return 0;

    int f=0;
    while(DFS(src,snk,f+1))f++;
    return f;
}

int deg[4050];

bool echk[2050];

vi Vl[4050];


int main(){
#ifdef happy
    freopen("in.txt","r",stdin);
#endif
    int  N1=rd(),N2=rd(),M=rd(),i,j,k;
    rep(i,1,M){
        int t1=rd(),t2=rd();
        deg[t1]++,deg[N1+t2]++;
        epush(t1,t2+N1,1);

        in[i][0]=t1;in[i][1]=t2;
    }
    int src=0,snk=N1+N2+1;
    rep(i,1,N1)epush(src,i,0);
    rep(i,1,N2)epush(i+N1,snk,0);

    int mn=INF;
    rep(i,1,N1+N2)
    mn=min(mn,deg[i]);

    puts("0");
    rep(q,1,mn){
        for(auto &it:Ve){
            if(it.s==src)it.f++;
            if(it.e==snk)it.f++;
        }
        int f=0,t;
        while(t=getFlow(src,snk))f+=t;

        rep(i,1,M)echk[i]=false;

        vi Va;
        rep(i,0,M-1)if(Ve[2*i].f==0)Va.pb(i+1),echk[i+1]=true;
        rep(i,1,N1+N2)Vl[i].clear();
        rep(i,1,M){
            if(echk[i])continue;
            Vl[in[i][0]].pb(i);
            Vl[in[i][1]+N1].pb(i);
        }

        for(auto &it:Ve){
            if(it.s!=src&&it.e!=snk)continue;
            int t=it.f;
            int n=it.e;
            if(it.e==snk)n=it.s;
            for(int i=0;i<it.f;i++)Va.pb(Vl[n][i]);
        }

        printf("%d ",Va.size());
        for(auto it:Va)printf("%d ",it);
        printf("\n");
    }

}

猜你喜欢

转载自blog.csdn.net/ujn20161222/article/details/80522619