Sentry Robots UVA

来源:互联网 发布:投资组合经理 知乎 编辑:程序博客网 时间:2024/05/17 10:41

题目链接:点击打开链接

题目大意:懒得说了

题目思路:看题目的的问法,我们很容易想到是最小点覆盖或者边覆盖的问题,我们可以发现对于某个重要的点(x,y),只用x,y其中一个点备选中就行,是不是发现了,就是最小点覆盖的定义:求最小数量的点,使得包括每条边的至少一个端点,所以,我们对于每一个重要位置的左边,根据行列建图,从x联向y,容量为1,然后求最小点覆盖,但是这里还有一个地方就是会有障碍点,那么我们可以先把每一行的坐标离散化,如果这一行有障碍,我们就加一,列的同理。。。

ac代码:

#include<cstdio>#include<queue>#include<iostream>#include<sstream>#include<map>#include<cstring>#define LL long long#define INF 0x3f3f3f3fusing namespace std;const int inf = 0x3f3f3f3f;const int MX = 200+5;const int MXE = 5 * MX * MX;int T;int n,m;int cnt1;int cnt2;int mp[105][105];int r[105][105];int c[105][105];struct MaxFlow{    struct Edge    {        int v, w, nxt;    } edge[MXE],edge2[MXE];    int tot, num, s, t;    int head[MX];    void init()    {        memset(head, -1, sizeof(head));        tot = 0;    }    void add(int u, int v, int w)    {        edge[tot].v = v;        edge[tot].w = w;        edge[tot].nxt = head[u];        head[u] = tot++;        edge[tot].v = u;        edge[tot].w = 0;        edge[tot].nxt = head[v];        head[v] = tot++;    }    int  d[MX], vis[MX], gap[MX];    void bfs()    {        memset(d, 0, sizeof(d));        memset(gap, 0, sizeof(gap));        memset(vis, 0, sizeof(vis));        queue<int>q;        q.push(t);        vis[t] = 1;        while (!q.empty())        {            int u = q.front();            q.pop();            for (int i = head[u]; ~i; i = edge[i].nxt)            {                int v = edge[i].v;                if (!vis[v])                {                    d[v] = d[u] + 1;                    gap[d[v]]++;                    q.push(v);                    vis[v] = 1;                }            }        }    }    int last[MX];    int dfs(int u, int f)    {        if (u == t) return f;        int sap = 0;        for (int i = last[u]; ~i; i = edge[i].nxt)        {            int v = edge[i].v;            if (edge[i].w > 0 && d[u] == d[v] + 1)            {                last[u] = i;                int tmp = dfs(v, min(f - sap, edge[i].w));                edge[i].w -= tmp;                edge[i ^ 1].w += tmp;                sap += tmp;                if (sap == f) return sap;            }        }        if (d[s] >= num) return sap;        if (!(--gap[d[u]])) d[s] = num;        ++gap[++d[u]];        last[u] = head[u];        return sap;    }    int solve(int st, int ed, int n)    {        int flow = 0;        num = n;        s = st;        t = ed;        bfs();        memcpy(last, head, sizeof(head));        while (d[s] < num) flow += dfs(s, inf);        return flow;    }} F;int main(){    scanf("%d",&T);    while(T--){        F.init();        memset(r,0,sizeof(r));        memset(c,0,sizeof(c));        memset(mp,0,sizeof(mp));        scanf("%d%d",&n,&m);        scanf("%d",&cnt1);        for(int i = 0;i<cnt1;i++){            int x,y;            scanf("%d%d",&x,&y);            mp[x][y] = 1;        }        scanf("%d",&cnt2);        for(int i = 0;i<cnt2;i++){            int x,y;            scanf("%d%d",&x,&y);            mp[x][y] = 2;        }        int N = 0;        for(int i = 1;i<=m;i++){            int ok = 1;            for(int j = 1;j<=n;j++){                if(mp[j][i]==1){                    if(ok)                        N++;                    r[j][i] = N;                    ok = 0;                }                else if(mp[j][i] == 2){                    ok = 1;                }            }        }        int M = 0;        for(int i = 1;i<=n;i++){            int ok = 1;            for(int j = 1;j<=m;j++){                if(mp[i][j]==1){                    if(ok)                        M++;                    c[i][j] = M+N;                    ok = 0;                }                else if(mp[i][j]==2){                    ok = 1;                }            }        }        for(int i = 1;i<=n;i++){            for(int j= 1;j<=m;j++){                if(mp[i][j] == 1){                    F.add(r[i][j],c[i][j],1);                }            }        }        int NN = N;        int MM = M;        N = M = 0;        for(int i = 1;i<=m;i++){            int ok = 1;            for(int j = 1;j<=n;j++){                if(mp[j][i]==1){                    if(ok){                        N++;                        F.add(NN+MM+1,N,1);                    }                    r[j][i] = N;                    ok = 0;                }                else if(mp[j][i] == 2){                    ok = 1;                }            }        }         for(int i = 1;i<=n;i++){            int ok = 1;            for(int j = 1;j<=m;j++){                if(mp[i][j]==1){                    if(ok){                        M++;                        F.add(M+N,NN+MM+2,1);                    }                    c[i][j] = M+N;                    ok = 0;                }                else if(mp[i][j]==2){                    ok = 1;                }            }        }        //cout<<N<<' '<<M<<endl;        int ans = F.solve(NN+MM+1,NN+MM+2,NN+MM+2);        cout<<ans<<endl;    }}


原创粉丝点击