zoukankan      html  css  js  c++  java
  • [SDOI2012]象棋

    题解:

    sd的题目也真是奇怪

    第一题有了最短路第二题还有

    第二题有了网络流第三题还有

    显然是可以网络流的

    但考虑每个点只能存在一个这个条件

    刚开始我以为是建分层图。。但发现这个时间复杂度太高了

    其实我们考虑当两个人到一个点的时候可以交换速度(常用思想)

    所以如果有解那么这个条件就是没有用的

    所以也就是说这个条件是没有用的

    那就变成了二分图最大权匹配

    代码:

    #include <bits/stdc++.h>
    #define N 40000
    #define maxn 500000
    using namespace std;
    struct re{
        int a,b,c,from,flow,cost;
    }a[maxn];
    struct ree{
        int a,b,c;
    }e[maxn];
    int l2,l,head[N],head2[N];
    void arr(int x,int y,int z,int flow,int cost)
    {
        a[++l].a=head[x];
        a[l].b=y;
        a[l].c=z;
        a[l].flow=flow;
        a[l].cost=cost;
        a[l].from=x;
        head[x]=l;
    }
    #define INF 1e9
    int sum,d[N],s,t,p[N],aa[N],n,m;
    bool inq[N];
    bool bellmanford(int &flow,int &cost)
    {
        for (int i=1;i<=sum;i++) d[i]=INF;
        memset(inq,0,sizeof(inq));
        d[s]=0; inq[s]=1; aa[s]=INF;
        queue<int>q;
        q.push(s);
        while (!q.empty())
        {
            int x=q.front(); q.pop();
            int u=head[x];
            while (u)
            {
                int v=a[u].b;
                if (a[u].c>a[u].flow&&d[v]>d[x]+a[u].cost)
                {
                  d[v]=d[x]+a[u].cost;
                  p[v]=u;
                  aa[v]=min(aa[x],a[u].c-a[u].flow);
                  if (!inq[v])
                  {
                      q.push(v); inq[v]=1;
                  }
                }
                u=a[u].a;
            }
            inq[x]=0;
        }
        if (d[t]==INF) return(0);
        flow+=aa[t];
        cost+=d[t]*aa[t];
        int x=t;
        while (x!=s)
        {
            int u=p[x];
            a[u].flow+=aa[t];
            if (u%2) a[u+1].flow-=aa[t]; else a[u-1].flow-=aa[t];
            x=a[u].from;
        }
        return 1;
    }
    int flow,cost;
    void mincost()
    {
        while (bellmanford(flow,cost));
    }
    int dx[5]={0,1,1,-1,-1};
    int dy[5]={0,1,-1,1,-1};
    queue<int> q;
    bool ff[1000][1000];
    char cc[N];
    int js(int x,int y)
    {
        return((x-1)*m+y);
    }
    bool pd(int x,int y)
    {
        if (x>=1&&x<=n&&y>=1&&y<=m&&!ff[x][y]) return(1);
        else return(0);
    }
    void arr2(int x,int y)
    {
        e[++l2].a=head2[x];
        e[l2].b=y;
        head2[x]=l2;
    }
    int k,a1,b1;
    int x1[N],x2[N],y3[N],y4[N],dis[N];
    bool vis[N];
    int main()
    {
      freopen("noi.in","r",stdin);
      freopen("noi.out","w",stdout);
        std::ios::sync_with_stdio(false);
        cin>>n>>m>>k>>a1>>b1;
        for (int i=1;i<=n;i++)
        {
            cin>>cc;
            int len=strlen(cc);
            for (int j=0;j<len;j++)
              if (cc[j]=='*') ff[i][j+1]=1;
        }
        for (int i=1;i<=k;i++)
          cin>>x1[i]>>y3[i];
        for (int i=1;i<=k;i++)
          cin>>x2[i]>>y4[i];
        for (int i=1;i<=n;i++)
          for (int j=1;j<=m;j++)
          if (pd(i,j))
          {
              for (int i1=1;i1<=4;i1++)
              {
                if (pd(i+dx[i1]*a1,j+dy[i1]*b1))
                {
                    int k1=js(i,j);
                    int k2=js(i+dx[i1]*a1,j+dy[i1]*b1);
                    arr2(k1,k2);
              }
              if (pd(i+dx[i1]*b1,j+dy[i1]*a1))
              {
                  int k1=js(i,j);
                  int k2=js(i+dx[i1]*b1,j+dy[i1]*a1);
                  arr2(k1,k2);
              }
            }
          }
        sum=2*k+1;
        for (int i=1;i<=k;i++)
        {
            int ax1=js(x1[i],y3[i]);
            for (int j=1;j<=n*m;j++)
              dis[j]=INF;
            memset(vis,0,sizeof(vis));
            dis[ax1]=0; q.push(ax1); vis[ax1]=1;
            while (!q.empty())
            {
                int x2=q.front(); q.pop();
                int u=head2[x2];
                while (u)
                {
                    int v=e[u].b;
                    if (!vis[v])
                    {
                        
                      dis[v]=dis[x2]+1;
                      q.push(v);
                      vis[v]=1;
                    }
                    u=e[u].a;
                }
            }
            for (int j=1;j<=k;j++)
            {
                int ax2=js(x2[j],y4[j]);
                arr(i,j+k,1,0,dis[ax2]);
                arr(j+k,i,0,0,-dis[ax2]);
            }
        }
        s=0; t=2*k+1;
        for (int i=1;i<=k;i++)
        {
            arr(s,i,1,0,0); arr(i,s,0,0,0);
            arr(i+k,t,1,0,0); arr(t,i+k,0,0,0);
        }
        mincost();
        cout<<cost;
        return 0;
    }
  • 相关阅读:
    sscanf()
    分享:Python字符编码详解
    STL priority_queue使用
    google maps 控件controller
    Google Maps Overlays叠加层
    java JDBC配置和使用
    转:总结java的interface和abstract class
    java 多线程 之 生产者和消费者
    一个简单的marker和infowindow
    java Nested Classes
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8823106.html
Copyright © 2011-2022 走看看