zoukankan      html  css  js  c++  java
  • 2014多校联合-第三场

    1002:Redraw Beautiful Drawings

    最大流。。。。用sap+gap优化的模版过的。。。

    1. 源点 -> 每一行相应的点,流量限制为该行的和

    2. 每一行相应的点 -> 每一列相应的点。流量限制为 K

    3. 每一列相应的点 -> 汇点,流量限制为该列的和

    跑一遍最大流。

    假设流量小于总权值和,那么说明impossible。

    假设等于:

    构建残图网络。假设残图网络能够形成一条回路,那么说明有多解。

    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include<queue>
    using namespace std;
    #define INF 99999999
    const int maxn =810;
    const int maxm =2*410*410+410*4;
    const int oo = 1<<29;
    struct Arclist
    {
        int cnt, head[maxn], dis[maxn];
        int cur[maxn], pre[maxn], gap[maxn], aug[maxn];
        int mp[maxn][maxn];
        int vis[maxn];
        int vis2[maxn];
        struct node
        {
            int u, v, w, next;
        }edge[maxm];
        void init()
        {
            cnt = 0;
            memset(head,-1,sizeof(head));
        }
        void add(int u, int v, int w)
        {
            edge[cnt].u = u;
            edge[cnt].v = v;
            edge[cnt].w = w;
            edge[cnt].next = head[u];
            head[u] = cnt++;
            edge[cnt].u = v;
            edge[cnt].v = u;
            edge[cnt].w = 0;
            edge[cnt].next = head[v];
            head[v] = cnt++;
        }
        int sap(int s, int e, int n)
        {
            int max_flow = 0, u = s;
            int mindis;
            for(int i = 0; i <= n; i++)
            {
                cur[i] = head[i];
                dis[i] = 0;
                gap[i] = 0;
            }
            aug[s] = oo;
            pre[s] = -1;
            gap[0] = n;
            while(dis[s]<n)
            {
                bool flag = false;
                if(u==e)
                {
                    max_flow += aug[e];
                    for(int v = pre[e]; v != -1; v = pre[v])
                    {
                        int id = cur[v];
                        edge[id].w -= aug[e];
                        edge[id^1].w += aug[e];
                        aug[v] -= aug[e];
                        if(edge[id].w==0) u = v;
                    }
                }
                for(int id = cur[u]; id != -1; id = edge[id].next)
                {
                    int v = edge[id].v;
                    if(edge[id].w>0 && dis[u]==dis[v]+1)
                    {
                        flag = true;
                        pre[v] = u;
                        cur[u] = id;
                        aug[v] = std::min(aug[u], edge[id].w);
                        u = v;
                        break;
                    }
                }
                if(flag==false)
                {
                    if(--gap[dis[u]]==0) break;
                    mindis = n;
                    cur[u] = head[u];
                    for(int id = head[u]; id != -1; id = edge[id].next)
                    {
                        int v = edge[id].v;
                        if(edge[id].w>0 && dis[v]<mindis)
                        {
                            mindis = dis[v];
                            cur[u] = id;
                        }
                    }
                    dis[u] = mindis+1;
                    ++gap[dis[u]];
                    if(u!=s) u = pre[u];
                }
            }
            return max_flow;
        }
        int n,m,k;
        int sou(int pre,int x,int leap)
        {
            vis2[x]=1;
            if(leap==0)
            {
                for(int i=n+1;i<=m+n;i++)
                {
                    if(i==pre)continue;
                    if(mp[x][i]==0)continue;
                    if(vis2[i])
                    {
                        vis2[x]=0;
                        return 1;
                    }
                    if(sou(x,i,1)){
                        vis2[x]=0;
                        return 1;
                    }
                }
            }
            if(leap==1)
            {
                for(int i=1;i<=n;i++)
                {
                    if(i==pre)continue;
                    if(mp[x][i]==0)continue;
                    if(vis2[i]){
                        vis2[x]=0;
                        return 1;
                    }
                    if(sou(x,i,0)){
                        vis2[x]=0;
                        return 1;
                    }
                }
            }
            vis2[x]=0;
            return 0;
        }
        int dfs()
        {
           memset(vis,0,sizeof(vis));
           memset(vis2,0,sizeof(vis2));
           for(int i=1;i<=n;i++)
           {
               if(vis[i])continue;
               if(sou(-1,i,0))return 1;
           }
           return 0;
        }
        void pan()
        {
            memset(mp,0,sizeof(mp));
            for(int i=0;i<cnt;i++)
            {
                int u=edge[i].u;
                int v=edge[i].v;
                int w=edge[i].w;
                if(u>n)continue;
                if(v<=n||v>n+m)continue;
                mp[u][v]=w;
                mp[v][u]=k-w;
            }
            if(dfs())
            {
                cout<<"Not Unique"<<endl;
                return ;
            }
            cout<<"Unique"<<endl;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(j!=1)cout<<" ";
                    printf("%d",k-mp[i][j+n]);
                }
                cout<<endl;
            }
        }
    }G;
    int a[510];
    int b[510];
    int main()
    {
        int m,n,k;
        while(~scanf("%d%d%d",&n,&m,&k))
        {
            int st=n+m+1;
            int ed=n+m+2;
            G.init();
            int ans=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                G.add(st,i,a[i]);
                ans+=a[i];
            }
            for(int i=n+1;i<=n+m;i++)
            {
                scanf("%d",&b[i]);
                G.add(i,ed,b[i]);
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=n+1;j<=n+m;j++)
                {
                    G.add(i,j,k);
                }
            }
            int mx;
            mx=G.sap(st,ed,n+m+2);
            if(mx<ans)cout<<"Impossible"<<endl;
            else
            {
                G.n=n;
                G.m=m;
                G.k=k;
                G.pan();
            }
        }
        return 0;
    }

    1003:Scary Path Finding Algorithm

    由题意可知,直接构造即可。。。

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<stdlib.h>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<set>
    using namespace std;
    void dos()
    {
        int a[31];
        a[0]=1;
        for(int i=1; i<=30; i++)
        {
            a[i]=a[i-1]*2;
        }
        int n=30*2+1;
        int m=30*3-3;
        cout<<n<<" "<<m<<endl;
        for(int i=1; i<=29; i++)
        {
            printf("%d %d %d
    ",i,i+30,0);
            printf("%d %d %d
    ",i,i+1,-a[30-i]);
            printf("%d %d %d
    ",i+30,i+1,-a[30-i+1]);
        }
    }
    long long spfa_slf()
    {
        int n,m;
        cin >> n >> m;
    
        vector<pair<int,int> > edges[111];
        for(int i = 0; i < m; i++)
        {
            int x,y,w;
            cin >> x >> y >> w;
            edges[x].push_back(make_pair(y,w));
        }
    
        deque<int> q;
        vector<long long> dist(n+1, ~0ULL>>1);
        vector<bool> inQueue(n+1, false);
        dist[1] = 0;
        q.push_back(1);
        inQueue[1] = true;
    
        int doge = 0;
        while(!q.empty())
        {
            int x = q.front();
            q.pop_front();
            if(doge++ > 23333333)
            {
                puts("doge");
                return 233;
            }
            for(vector<pair<int,int> >::iterator it = edges[x].begin();
                    it != edges[x].end(); ++it)
            {
                int y = it->first;
                int w = it->second;
                if(dist[y] > dist[x] + w)
                {
                    dist[y] = dist[x] + w;
                    if(!inQueue[y])
                    {
                        inQueue[y] = true;
                        if(!q.empty() && dist[y] > dist[q.front()])
                            q.push_back(y);
                        else
                            q.push_front(y);
                    }
                }
            }
            inQueue[x] = false;
        }
        return dist[n];
    }
    int main()
    {
        int n;
       // freopen("data.in","r",stdin);
        while(~scanf("%d",&n))
        {
            dos();
        }
       // spfa_slf();
       // cout<<"-00"<<endl;
        return 0;
    }









  • 相关阅读:
    Linux 网络编程之ioctl函数
    驱动编写及编译例子
    字符串字面量与指针
    ubuntu 下安装nfs
    android 开源项目
    【转】中间件的历史来看移动App开发的未来
    android 关联源码
    【转】android 蓝牙
    【转】Android Google Map API使用的八个步骤
    【转】Android 国内集成使用谷歌地图
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7287245.html
Copyright © 2011-2022 走看看