Member Single Round Match 465 Round 1 - Division I, Level Two GreenWarfareze

来源:互联网 发布:js全局变量和局部变量 编辑:程序博客网 时间:2024/06/05 22:50

有一些敌军据点,有一些能源基地,基地给和它距离小于R的点提供能量。你有一些炮台,摧毁一个据点有两种方法,一种是直接摧毁据点,一种是摧毁给他提供能源的所有基地。用一个炮台摧毁一个目标的代价是欧几里得距离的平方。问你摧毁所有据点的最小代价。

解法:二分图最小点权覆盖。

预处理出摧毁一个基地和一个据点的的最小代价。以据点为X部,源点连流量为摧毁代价的边,基地为Y部,汇点连流量为摧毁代价的边,如果一个基地给一个据点提供能量,在两部之间连接流量为无穷的边。从源点向汇点求最小割(最大流)即可。

#include <bits/stdc++.h>#define maxn 1009#define maxm 2000009#define INF 1e9using namespace std;struct Edge{    int v,next,cap;}edge[maxm];int head[maxn],h[maxn],gap[maxn],tot,n,src,des,N;inline void addedge(int u,int v,int cap){    edge[tot].v=v;    edge[tot].cap=cap;    edge[tot].next=head[u];    head[u]=tot++;    edge[tot].v=u;    edge[tot].cap=0;    edge[tot].next=head[v];    head[v]=tot++;}int dis(int x1,int y1,int x2,int y2){return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);}inline int dfs(int u,int cap){    if(u==des)return cap;    int minh=n-1;    int lv=cap,d;    for(int e=head[u];e!=-1;e=edge[e].next)    {        int v=edge[e].v;        int w=edge[e].cap;        if(w>0)        {            if(h[v]+1==h[u])            {                d=min(lv,edge[e].cap);                d=dfs(v,d);                edge[e].cap-=d;                edge[e^1].cap+=d;                lv-=d;                if(h[src]>=n)return cap-lv;                if(lv==0)                    break;            }            minh=min(minh,h[v]);        }    }    if(lv==cap)    {        --gap[h[u]];        if(gap[h[u]]==0)h[src]=n;        h[u]=minh+1;        ++gap[h[u]];    }    return cap-lv;}int sap(){    int res=0;    memset(gap,0,sizeof(gap));    memset(h,0,sizeof(h));    gap[0]=n;    while(h[src]<n)res+=dfs(src,INF);    return res;}class GreenWarfare{public:int minimumEnergyCost(vector <int> canonX, vector <int> canonY, vector <int> baseX, vector <int> baseY, vector <int> plantX, vector <int> plantY, int energySupplyRadius){int base=baseX.size();src=0;memset(head,-1,sizeof(head));tot=0;for(int i=0;i<base;i++){int cur=INF;for(int j=0;j<(int)canonX.size();j++){cur=min(cur,dis(canonX[j],canonY[j],baseX[i],baseY[i]));}addedge(src,i+1,cur);}int plant=plantX.size();des=base+plant+1;n=des+1;for(int i=0;i<plant;i++){int cur=INF;for(int j=0;j<(int)canonX.size();j++){cur=min(cur,dis(plantX[i],plantY[i],canonX[j],canonY[j]));}addedge(base+i+1,des,cur);}for(int i=0;i<base;i++){for(int j=0;j<plant;j++){if(dis(baseX[i],baseY[i],plantX[j],plantY[j])<=energySupplyRadius*energySupplyRadius){addedge(i+1,j+base+1,INF);}}}return sap();}};


0 0
原创粉丝点击