最小割。
二分方法中:
while(begin<=end)
{
mid=(begin+end)>>1;
build(mid);
if(m*xx-solve()>0) begin=mid+1;
else
end=mid-1;
}
最后 end<ans*<=begin.
最大权值为begin,但要求定点集,要用end。
代码:
#include<iostream>
#include<fstream>
#include<queue>
#define xx 1000000
using namespace std;
int n;
int c[1110][1110],f[1110][1110];
int d[1110];
int flow;
int v[1110];
typedef struct e{
int data;
e *next;
}e;
e edge[1110];
int build(){
int i,j,k;
queue<int> q;
q.push(1);
memset(d,0,sizeof(d));
d[1]=1;
while(!q.empty())
{
i=q.front();
q.pop();
e *p=edge[i].next;
while(p)
{
j=p->data;
if(d[j]==0&&c[i][j]>f[i][j])
{
d[j]=d[i]+1;
if(j==n) return 1;
q.push(j);
}
p=p->next;
}
}
return 0;
}
int find(int m,int minw){
int i,k;
int j;
if(m==n) return minw;
v[m]=1;
e *p=edge[m].next;
while(p)
{
i=p->data;
if(c[m][i]>f[m][i]&&d[i]==d[m]+1&&v[i]==0)
{
j=find(i,min(minw,c[m][i]-f[m][i]));
if(j)
{
f[m][i]+=j;
f[i][m]=-1*f[m][i];
return j;
}
}
p=p->next;
}
return 0;
}
int solve(){
int i,j;
int k;
flow=0;
memset(f,0,sizeof(f));
while(build())
while(1){
memset(v,0,sizeof(v));
i=(~0u)>>1;
k=find(1,i);
flow+=k;
if(k==0) break;
}
return flow;
}
int ans,m;
void build(int mid){
int i;
for(i=1+m+1;i<=n-1;i++)
c[i][n]=mid;
}
void dfs(int s){
e *p=edge[s].next;
v[s]=1;
while(p){
if(v[p->data]==0&&c[s][p->data]>f[s][p->data])
{
dfs(p->data);
if(p->data>1+m) ans++;
}
p=p->next;
}
}
void read(){
// ifstream cin("in.txt");
int i,j,k,s,t;
cin>>n>>m;
// scanf("%d%d",&n,&m);
if(m==0)
{
cout<<1<<endl;
cout<<1<<endl;
return ;
}
for(i=1;i<=m;i++)
{
c[1][i+1]=xx;
e*p=new e;
p->data=i+1;
p->next=edge[1].next;
edge[1].next=p;
e *q=new e;
q->data=1;
q->next=edge[i+1].next;
edge[i+1].next=q;
}
for(i=1;i<=n;i++)
{
e*p=new e;
p->data=i+1+m;
p->next=edge[m+n+2].next;
edge[n+m+2].next=p;
e *q=new e;
q->data=m+n+2;
q->next=edge[i+1+m].next;
edge[i+1+m].next=q;
}
for(i=1;i<=m;i++)
{
cin>>s>>t;
// scanf("%d%d",&s,&t);
c[i+1][s+1+m]=(~0u)>>1;
e *p=new e;
p->data=i+1;
p->next=edge[s+1+m].next;
edge[s+1+m].next=p;
e *q=new e;
q->data=s+1+m;
q->next=edge[i+1].next;
edge[i+1].next=q;
c[i+1][t+1+m]=(~0u)>>1;
e *p1=new e;
p1->data=i+1;
p1->next=edge[t+1+m].next;
edge[t+1+m].next=p1;
e *q1=new e;
q1->data=t+1+m;
q1->next=edge[i+1].next;
edge[i+1].next=q1;
}
n=n+m+2;
int begin,end,mid;
begin=0;end=m*xx;
while(begin<=end)
{
mid=(begin+end)>>1;
build(mid);
if(m*xx-solve()>0) begin=mid+1;
else
end=mid-1;
}
for(i=1+m+1;i<=n-1;i++)
c[i][n]=end;
solve();
memset(v,0,sizeof(v));
ans=0;
dfs(1);
cout<<ans<<endl;
for(i=1+m+1;i<=n-1;i++)
{
if(v[i])
cout<<i-m-1<<endl;
}
}
int main(){
read();
return 0;
}