本题是求最大点割集。
首先,构造图。
对于点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
ID: lorelei3
 TASK: telecow
TASK: telecow
 LANG: C++
LANG: C++
 */
*/

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

 using namespace std;
using namespace std;

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


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

 Tadj()
    Tadj() {
{
 cnt=0;
        cnt=0;
 }
    }

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


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

 Tqueue()
    Tqueue() {
{
 reset();
        reset();
 }
    }


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


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


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


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


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


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


 Tstack()
    Tstack() {
{
 reset();
        reset();
 }
    }


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


 void pop()
    void pop() {
{
 top--;
        top--;
 }
    }


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

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

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

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


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


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


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

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


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


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

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

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


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

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

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


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

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

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


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


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

 if(u!=t)
    if(u!=t) {
{

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

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

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


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

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


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


 void solve()
void solve() {
{
 int cnt = 0;
    int cnt = 0;

 Dinic();
    Dinic();
 maxflow = max_flow();
    maxflow = max_flow();


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

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


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

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


 int main()
int main() {
{

 input();
    input();

 solve();
    solve();

 output();
    output();

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