• 【LA4043 训练指南】蚂蚁 【二分图最佳完美匹配,费用流】


    题意

      给出n个白点和n个黑点的坐标,要求用n条不相交的线段把他们连接起来,其中每条线段恰好连接一个白点和一个黑点,每个点恰好连接一条线段。

    分析

      结点分黑白,很容易想到二分图。其中每个白点对应一个X结点,每个黑点对应一个Y点,每个黑点和每个白点相连,权值等于二者的欧几里得距离,建模之后,最佳完美匹配就是问题的解。

      为什么用费用流而不用KM呢,因为我不会···

      

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <iostream>
      5 #include <vector>
      6 #include <queue>
      7 #include <cmath>
      8 
      9 using namespace std;
     10 const int maxN=300;
     11 const int maxm=30000+10;
     12 const int INF=2147480000;
     13 int n;
     14 int ax[maxN],bx[maxN],ay[maxN],by[maxN];
     15 
     16 struct MCMF{
     17     int head[maxN],to[maxm],Next[maxm],from[maxm],flow[maxm],cap[maxm];
     18     double cost[maxm];
     19     int n,m,s,t,sz;
     20     int inq[maxN];
     21     double d[maxN];
     22     int p[maxN];
     23     int a[maxN];
     24 
     25     void init(int n){
     26         this->n=n;
     27         sz=-1;
     28         memset(head,-1,sizeof(head));
     29     }
     30     void AddEdge(int a,int b,int ca,double co){
     31         ++sz;
     32         to[sz]=b,from[sz]=a,Next[sz]=head[a],head[a]=sz;
     33         flow[sz]=0,cap[sz]=ca,cost[sz]=co;
     34         ++sz;
     35         to[sz]=a,from[sz]=b,Next[sz]=head[b],head[b]=sz;
     36         flow[sz]=ca,cap[sz]=ca,cost[sz]=-co;
     37     }
     38     bool BellmanFord(int s,int t,int &Flow,double &Cost){
     39         for(int i=0;i<=n;i++)d[i]=INF;
     40         memset(inq,0,sizeof(inq));
     41         d[s]=0;inq[s]=1;p[s]=-1;a[s]=INF;
     42         queue<int>Q;
     43         Q.push(s);
     44         while(!Q.empty()){
     45             int u=Q.front();Q.pop();
     46             inq[u]=0;
     47             for(int i=head[u];i!=-1;i=Next[i]){
     48                 int v=to[i];
     49                 if(cap[i]>flow[i]&&d[v]>d[u]+cost[i]){
     50                     d[v]=d[u]+cost[i];
     51                     p[v]=i;
     52                     a[v]=min(a[u],cap[i]-flow[i]);
     53                     if(!inq[v]){
     54                         Q.push(v);
     55                         inq[v]=1;
     56                     }
     57                 }
     58             }
     59         }
     60         if(d[t]==INF)return false;
     61         Flow+=a[t];
     62         Cost+=d[t]*(double)a[t];
     63         int u=t;
     64 
     65         while(u!=s){
     66             flow[p[u]]+=a[t];
     67             flow[p[u]^1]-=a[t];
     68             u=from[p[u]];
     69         }
     70         return true;
     71     }
     72 
     73     double Mincost(int s,int t){
     74         int Flow=0;
     75         double Cost=0;
     76         while(BellmanFord(s,t,Flow,Cost));
     77         return Cost;
     78     }
     79 }mcmf;
     80 
     81 double dist(int X,int Y){
     82     return sqrt((double)(ax[X]-bx[Y])*(ax[X]-bx[Y])+(double)(ay[X]-by[Y])*(ay[X]-by[Y]));
     83 }
     84 int main(){
     85     while(scanf("%d",&n)!=EOF){
     86         for(int i=1;i<=n;i++)
     87             scanf("%d%d",&ax[i],&ay[i]);
     88         for(int i=1;i<=n;i++)
     89             scanf("%d%d",&bx[i],&by[i]);
     90         mcmf.init(2*n+2);
     91         for(int i=1;i<=n;i++)
     92             mcmf.AddEdge(0,i,1,0);
     93         for(int i=1;i<=n;i++)
     94             mcmf.AddEdge(i+n,2*n+1,1,0);
     95         for(int i=1;i<=n;i++){
     96             for(int j=1;j<=n;j++){
     97                 mcmf.AddEdge(i,j+n,1,dist(i,j));
     98             }
     99         }
    100         mcmf.Mincost(0,2*n+1);
    101         for(int i=1;i<=n;i++){
    102             for(int j=mcmf.head[i];j!=-1;j=mcmf.Next[j]){
    103                 if(j%2)continue;
    104                 int v=mcmf.to[j];
    105                 if(mcmf.cap[j]==mcmf.flow[j]){
    106                     printf("%d
    ",v-n);
    107                     break;
    108                 }
    109             }
    110         }
    111     }
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    Linux0.12内存寻址
    Linux0.12任务调度与进程切换
    Mapreduce实例——倒排索引
    解决echart警告:Can't get dom width or height
    Mapreduce实例——MapReduce自定义输入格式
    Mapreduce实例——ChainMapReduce
    Mapreduce实例——二次排序
    设计模式中介者模式
    设计模式七大原则
    Mapreduce实例——MapReduce自定义输出格式
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9306503.html
Copyright © 2020-2023  润新知