zoukankan      html  css  js  c++  java
  • Gym100218I Roundtrip

    Link
    首先给出一个有解的必要条件:存在(a ightarrow c ightarrow b)的一条点不相交路径。
    必要性是显然的。
    注意到保证存在(3)(a ightarrow b)的点不相交路径,因此这个条件也具有充分性,具体可以通过调整法证明。
    那么我们先用最大流找出三条(a ightarrow b)的路径,然后枚举其中一条作为最后环路中的(a ightarrow b)的路径,再在残量网络(只考虑这一条(a ightarrow b)的路径的流量)上跑出(a ightarrow c ightarrow b)的路径即可。

    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    const int V=20007,E=220007;
    int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
    int n,m,a,b,c,s,t,tot=1,head[V],ver[E],next[E],edge[E],vis[V],pre[V];
    std::vector<int>vec[3],pat[3],ans;std::queue<int>q;
    void add(int u,int v){ver[++tot]=v,next[tot]=head[u],edge[tot]=1,head[u]=tot,ver[++tot]=u,next[tot]=head[v],head[v]=tot;}
    int bfs()
    {
        while(!q.empty()) q.pop();
        memset(vis,0,sizeof vis),q.push(s),vis[s]=1;
        for(int i,u,v;!q.empty();) for(i=head[u=q.front()],q.pop();i;i=next[i]) if(edge[i]&&!vis[v=ver[i]]) if(vis[v]=1,pre[v]=i,q.push(v),v==t) return 1;
        return 0;
    }
    int find()
    {
        if(!bfs())return 0;
        for(int p=t;p^s;p=ver[pre[p]^1])--edge[pre[p]],++edge[pre[p]^1];
        return 1;
    }
    int flow()
    {
        int ans=0;
        while(find())++ans;
        return ans;
    }
    void dfs(int u,std::vector<int>&vec)
    {
        if(u<=n) vec.push_back(u);
        if(u==t) return ;
        for(int i=head[u];i;i=next[i]) if(edge[i^1]&&~i&1) {dfs(ver[i],vec),++edge[i],--edge[i^1];break;}
    }
    int check(int id)
    {
        int f=1;
        for(int x:vec[id]) f&=x!=c;
        return f;
    }
    int main()
    {
        freopen("roundtrip.in","r",stdin),freopen("roundtrip.out","w",stdout);
        n=read(),m=read(),a=read(),b=read(),c=read(),s=a+n,t=b;
        for(int i=1,u,v;i<=m;++i) u=read(),v=read(),add(u+n,v),add(v+n,u);
        for(int i=1;i<=n;++i) add(i,i+n);
        for(int i=0;i<3;++i) find();
        for(int i=0;i<3;++i) dfs(s,vec[i]);
        add(a+n,n+n+1),add(b+n,n+n+1),s=c+n,t=n+n+1;
        for(int i=0,f;i<3;++i)
        {
    	if(!check(i)) continue;
    	for(int j=0;j+1<(int)vec[i].size();++j) for(int k=head[vec[i][j]];k;k=next[k]) if(ver[k]==vec[i][j]+n) edge[k]=0;
    	f=flow();
    	for(int j=0;j<f;++j) pat[j].clear(),dfs(s,pat[j]);
    	if(f==2)
    	{
    	    if(pat[0].back()==b) std::swap(pat[0],pat[1]);
    	    std::reverse(pat[0].begin(),pat[0].end()),ans=pat[0],ans.push_back(c),ans.insert(ans.end(),pat[1].begin(),pat[1].end()),vec[i].pop_back(),std::reverse(vec[i].begin(),vec[i].end()),ans.insert(ans.end(),vec[i].begin(),vec[i].end()),ans.push_back(a),printf("%d
    ",(int)ans.size()-1);
    	    for(int x:ans) printf("%d ",x);
    	    return 0;
    	}
    	for(int j=0;j+1<(int)vec[i].size();++j) for(int k=head[vec[i][j]];k;k=next[k]) if(ver[k]==vec[i][j]+n) edge[k]=1;	
        }
        puts("-1");
    }
    
  • 相关阅读:
    Audacious 1.3.0
    medit-多平台的 GTK 文本编辑器
    PIDA:基于 Gtk 的 Python IDE
    Xfce 4.4.0 for Ubuntu Edgy Eft
    Lemonrip-DVD 提取对象
    Tomboy 0.5.5
    网管经验谈:成功网管必备素质硬件篇
    再学 GDI+[35]: TGPPen 虚线画笔位移 SetDashOffset
    再学 GDI+[33]: TGPPen 画笔的几何变换 SetTransform
    再学 GDI+[37]: TGPPen TGPCustomLineCap、SetCustomStartCap、SetCustomEndCap
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12617397.html
Copyright © 2011-2022 走看看