zoukankan      html  css  js  c++  java
  • E

    题目链接:https://cn.vjudge.net/contest/281959#problem/E

    题目大意:中文题目

    具体思路:首先,有矛盾的时候就是两个导弹的运动轨迹会相交的时候,那么我们可以按照这样的思路,在每个导弹不想交的前提下,使得总的消灭数最大。然后我们就可以了按照会相交的方式建图,求出最小割,然后再用总和减去最小割,就能得出最大的消灭量了。

    建图的时候,首先横点向竖点连边,权值是inf。每一个炮弹记录他能打到的最大的消灭数,然后对于横着的炮台,从当前的炮台出发到最大的消灭数所在的位置,每一步的权值就是max-当前这个点的权值,最终求的答案的时候,所有炮台的最大值的总和-最小割就是最大消灭数了。

    AC代码:

      1 #include<iostream>
      2 #include<stack>
      3 #include<queue>
      4 #include<iomanip>
      5 #include<stdio.h>
      6 #include<cstring>
      7 #include<cstring>
      8 #include<cmath>
      9 #include<algorithm>
     10 #include<map>
     11 #include<vector>
     12 using namespace std;
     13 # define ll long long
     14 const int maxn = 50000+100;
     15 const int inf = 0x3f3f3f3f;
     16 int prev[maxn];
     17 int head[maxn];
     18 int dx[10]= {-1,1,0,0};
     19 int dy[10]= {0,0,-1,1};
     20 int A[600][600],B[600][600],w[600][600];
     21 struct node
     22 {
     23     int to;
     24     int flow;
     25     int nex;
     26 } edge[maxn];
     27 int num,st,ed;
     28 void init()
     29 {
     30     memset(head,-1,sizeof(head));
     31     num=0;
     32 }
     33 void addedge(int fr,int to,int flow)
     34 {
     35     edge[num].to=to;
     36     edge[num].flow=flow;
     37     edge[num].nex=head[fr];
     38     head[fr]=num++;
     39     edge[num].to=fr;
     40     edge[num].flow=0;
     41     edge[num].nex=head[to];
     42     head[to]=num++;
     43 }
     44 bool bfs()
     45 {
     46     memset(prev,-1,sizeof(prev));
     47     prev[st]=1;
     48     queue<int>q;
     49     q.push(st);
     50     while(!q.empty())
     51     {
     52         int top=q.front();
     53         q.pop();
     54         for(int i=head[top]; i!=-1; i=edge[i].nex)
     55         {
     56             int temp=edge[i].to;
     57             if(prev[temp]==-1&&edge[i].flow>0)
     58             {
     59                 prev[temp]=prev[top]+1;
     60                 q.push(temp);
     61             }
     62         }
     63     }
     64     return prev[ed]!=-1;
     65 }
     66 int dfs(int u,int flow)
     67 {
     68     if(u==ed)
     69         return flow;
     70     int res=0;
     71     for(int i=head[u]; i!=-1; i=edge[i].nex)
     72     {
     73         int t=edge[i].to;
     74         if(prev[t]==(prev[u]+1)&&edge[i].flow>0)
     75         {
     76             int temp=dfs(t,min(flow,edge[i].flow));
     77             edge[i].flow-=temp;
     78             edge[i^1].flow+=temp;
     79             res+=temp;
     80             flow-=temp;
     81             if(flow==0)
     82                 break;
     83         }
     84     }
     85     if(res==0)
     86         prev[u]=-1;
     87     return res;
     88 }
     89 int n,m;
     90 int dinic()
     91 {
     92     int ans=0;
     93     while(bfs())
     94     {
     95         ans+=dfs(st,inf);
     96     }
     97     return ans;
     98 }
     99 int cal()
    100 {
    101     int ans=0,x,y;
    102     for (int i = 1; i <= n; i++)
    103         for (int j = 1; j <= m; j++)
    104         {
    105             if (w[i][j] >= 0) continue;
    106             int dir = -(w[i][j] + 1),Max = w[i][j] = 0;
    107             for (int x = i + dx[dir],y = j + dy[dir]; ;)
    108             {
    109                 if (x < 1 || x > n || y < 1 || y > m) break;
    110                 Max = max(Max,w[x][y]); x += dx[dir]; y += dy[dir];
    111             }
    112             ans += Max;
    113             if (dir <= 1)
    114             {
    115                 addedge(st,A[i][j],inf);
    116                 for (int x = i + dx[dir],y = j + dy[dir]; ;)
    117                 {
    118                     if (x < 1 || x > n || y < 1 || y > m) break;
    119                     addedge(A[x - dx[dir]][y - dy[dir]],A[x][y],Max - w[x - dx[dir]][y - dy[dir]]);
    120                     x += dx[dir]; y += dy[dir];
    121                 }
    122             }
    123             else
    124             {
    125                addedge(B[i][j],ed,inf);
    126                 for (int x = i + dx[dir],y = j + dy[dir]; ;)
    127                 {
    128                     if (x < 1 || x > n || y < 1 || y > m) break;
    129                     addedge(B[x][y],B[x - dx[dir]][y - dy[dir]],Max - w[x - dx[dir]][y - dy[dir]]);
    130                     x += dx[dir]; y += dy[dir];
    131                 }
    132             }
    133         }
    134     return ans;
    135 }
    136 int main()
    137 {
    138     init();
    139     int tot=0;
    140     scanf("%d %d",&n,&m);
    141     for(int i=1; i<=n; i++)
    142     {
    143         for(int j=1; j<=m; j++)
    144         {
    145             A[i][j]=++tot,B[i][j]=++tot;
    146             scanf("%d",&w[i][j]);
    147             addedge(A[i][j],B[i][j],inf);
    148         }
    149     }
    150     st=++tot,ed=++tot;
    151     int sum=cal();
    152     int ans=dinic();
    153   //  cout<<sum<<" "<<ans<<endl;
    154     printf("%d
    ",sum-ans);
    155     return 0;
    156 }
  • 相关阅读:
    学Java需要了解的linux系统和unix系统
    51Nod 1649: 齐头并进(最短路)
    51Nod 1694: 两条路径(图论)
    The Preliminary Contest for ICPC Asia Shanghai 2019
    牛客练习赛52 A:数数(快速幂)
    The Preliminary Contest for ICPC Asia Shenyang 2019
    The 2019 Asia Nanchang First Round Online Programming Contest
    2019 年百度之星·程序设计大赛
    2019中国大学生程序设计竞赛(CCPC)
    2019 年百度之星·程序设计大赛
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10381602.html
Copyright © 2011-2022 走看看