本题是求最大点割集。
首先,构造图。
对于点i,分成u和v两点,并且dist[u][v]=1,dist[v][u]=0;
对于边(i, j), 对于i,根据上述方法分成a1,a2两点,j分成b1,b2; 使dist[b1][a2]=INF,dist[a2][b1]=0; dist[b2][a1]=INF,dist[a1][b2]=0;
然后根据最大流最小割定理,求最大流,使用Dinic。
Dinic的原理是先用bfs构建层次图。判断原点是否在层次图中,如果在,则从原点开始dfs求增广路径,用栈保存路径,求得之后增广之,增广之后有边变为0,则退栈到从原点可达的最远的点。继续dfs求增广路径。如果原点不在层次图,则结束Dinic
重复上述过程。
求得最大流为maxflow
最后求最大点割集,使用cnt作为记号,初始为0,枚举各点,删除之(即删除该点对应的边),然后求当前最大流nowflow,
若nowflow+1 ==maxflow+cnt ;
则cnt ++ ,记录这个点。

/**//*
ID: lorelei3
TASK: telecow
LANG: C++
*/

#include <fstream>
#include <memory.h>

using namespace std;

const int MAX = 300;
const int INF = 0x7FFFFFFF;


class Tadj
{
public:
int cnt;
int to[MAX];

Tadj()
{
cnt=0;
}

void ins(int k)
{
to[++cnt]=k;
}
};


class Tqueue
{
private:
long first, last, size;
long list[MAX*MAX];
public:

Tqueue()
{
reset();
}


void reset()
{
first=1, last=0, size=0;
}


void push_back(int k)
{
++size;
list[++last]=k;
}


void pop_front()
{
size--;
first++;
}


long front()
{
return list[first];
}


bool empty()
{
return size==0;
}
};


class Tstack
{
public:
int stack[MAX];
int top, min, p;


Tstack()
{
reset();
}


void reset()
{
top=0, min=INF;
}


void pop()
{
top--;
}


void push(int k)
{
stack[++top]=k;
}
};

ifstream fin("telecow.in");
ofstream fout("telecow.out");

Tqueue Q;
Tstack S;
Tadj adj[MAX];

int s,t,c1,c2,m,n,maxflow;
int level[MAX], set[MAX];
int dist[MAX][MAX], odist[MAX][MAX], flow[MAX][MAX];
bool used[MAX];


inline void insert(int u, int v, int cost)
{
adj[u].ins(v);
dist[u][v]=cost;
}


void input()
{
int i,u,v;
fin>>n>>m>>c1>>c2;


if(c1>c2)
{int c=c1, c1=c2, c2=c;}

for(i=1; i<=n; ++i)
{
u = i*2-1;
v = i*2;
insert(u, v, 1);
insert(v, u, 0);
}


for(i=1; i<=m; ++i)
{
fin>>u>>v;


if(u>v)
{ int c=u, u=v, v=c;}

int a1=u*2-1, a2=u*2;
int b1=v*2-1, b2=v*2;
insert(a2, b1, INF);
insert(b1, a2, 0);
insert(b2, a1, INF);
insert(a1, b2, 0);
}

s=c1*2;
t=c2*2-1;
adj[t].cnt=0;
memcpy(odist, dist, sizeof(dist));
}


void Dinic_Level()
{
Q.reset();
memset(used, 0, sizeof(used));
memset(level, 0, sizeof(level));
Q.push_back(s);

while(!Q.empty())
{
int u = Q.front();
Q.pop_front();
used[u]=true;

for(int i=1; i<=adj[u].cnt; ++i)
{
int v = adj[u].to[i];
if(!dist[u][v]) continue;
if(used[v] || v==1) continue;
level[v] = level[u]+1;
Q.push_back(v);
}
}
}


void Dinic_Argument()
{
S.stack[0]=s;

for(int i=1; i<=S.top; ++i)
{
int u = S.stack[i-1];
int v = S.stack[i];

if(dist[u][v]<S.min)
{
S.min = dist[u][v];
S.p = u;
}
}


for(int j=S.top; j>=1; --j)
{
int u = S.stack[j-1];
int v = S.stack[j];
flow[u][v] += S.min;
dist[u][v] -= S.min;
dist[v][u] += S.min;
}
}


bool Dinic_dfs(int u)
{
int outdegree=0;

if(u!=t)
{

for(int i=1; i<=adj[u].cnt; ++i)
{
int v = adj[u].to[i];

if(level[v]==level[u]+1 && dist[u][v])
{
outdegree++;
S.push(v);
bool f = Dinic_dfs(v);
S.pop();
if(f && u!=S.p)
return true;
}
}
if(outdegree==0)
level[u]=0;

}else
{
Dinic_Argument();
return true;
}
return false;
}


void Dinic()
{
memset(flow, 0, sizeof(flow));

for( ; ; )
{
Dinic_Level();
if(level[t]==0)
return;
S.reset();
Dinic_dfs(s);
}
}


long max_flow()
{
long ret = 0;
for(int i=1; i<=n*2; ++i)
ret += flow[s][i];
return ret;
}


void solve()
{
int cnt = 0;

Dinic();
maxflow = max_flow();


for(int i=1; i<=n; ++i)
{

if(i!=c1 && i!=c2)
{
int u=i*2-1;
int v=i*2;
odist[u][v]=0;
memcpy(dist, odist, sizeof(odist));
Dinic();
int nowflow = max_flow();
if(nowflow+1==maxflow-cnt)
set[++cnt]=i;
else
odist[u][v]=1;
}
if(cnt==maxflow)
return;
}
}


void output()
{
fout<<maxflow<<endl;

fout<<set[1];
for(int i=2; i<=maxflow; ++i)
fout<<" "<<set[i];
fout<<endl;
}


int main()
{

input();

solve();

output();

return 0;
}
posted on 2011-02-17 13:47
小阮 阅读(741)
评论(0) 编辑 收藏 引用 所属分类:
USACO