第一问是求最小割。第二问求最小割中集合中边最少的集合的大小。
第三问求集合中边最少且字典序最小的边的下标。
第一问直接求最大流就能解,第二问将原来的边的容量都改为1,求出来的最大流就是元素最少的一个最小割的大小。
将容量都改为1之后,直接枚举每个边和前面已经找到的边在同一个集合中,是的话输出边的下标。
/*
ID: modengd1
PROG: milk6
LANG: C++
*/
#include
#include
#include
#include
#include
using namespace std;
int N,M;
int level[33];
int input[33][33];
int inputC[33][33];
struct Edge
{int x,y,w;
};
vector Edges;
void BFS(int s)
{memset(level,-1,sizeof(level));level[s]=0;queue Q;Q.push(s);while(!Q.empty()){int now=Q.front();Q.pop();for(int i=1;i<=N;i++){if(input[now][i]&&level[i]<0){level[i]=level[now]+1;Q.push(i);}}}
}
int DFS(int s,int t,int f)
{if(s==t)return f;for(int i=1;i<=N;i++){if(input[s][i]&&level[i]==level[s]+1){int d=DFS(i,t,min(f,input[s][i]));if(d>0){input[s][i]-=d;input[i][s]+=d;return d;}}}return 0;
}
int max_flow(int s,int t)
{int flow=0;while(true){BFS(s);if(level[t]<0)return flow;int f;while((f=DFS(s,t,0x7fffffff))>0){flow+=f;} }
}
int main()
{freopen("milk6.in","r",stdin);freopen("milk6.out","w",stdout);scanf("%d%d",&N,&M);memset(input,0,sizeof(input));for(int i=0;i