60pts求助
查看原帖
60pts求助
420129
Nt_Tsumiki楼主2022/10/12 19:56
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
#include <map>

#define INF 1145141919

namespace Dinic_mcmf {
    struct Node {
        int to,nxt,dis,val;
    }e[10001];

    int tot=1,s,t,mcmf,head[10001],cur[10001],vis[10001],dis[10001];

    void add(int x,int y,int k,int v) { e[++tot]=(Node){y,head[x],k,v},head[x]=tot; }

     bool SPFA(int n) {
        for (int i=0;i<=2*n+1;i++) dis[i]=INF;
        std::queue<int> q; std::memset(vis,0,sizeof vis);
        q.push(s); dis[s]=0; vis[s]=1;
        while (!q.empty()) {
            int x=q.front(); q.pop();
            vis[x]=0;
            for (int i=head[x];i;i=e[i].nxt) {
                int y=e[i].to; cur[x]=head[x];
                if (e[i].dis and dis[y]>dis[x]+e[i].val) {
                    dis[y]=dis[x]+e[i].val; 
                    if (!vis[y]) q.push(y),vis[y]=1;
                }
            }
        }
        return dis[t]!=INF;
    }

    int dfs(int x,int flow) {
        if (x==t) return flow;
        int res=0;
        vis[x]=1;
        for (int &i=cur[x];i and flow;i=e[i].nxt) {
            int y=e[i].to;
            if (!vis[y] and e[i].dis and dis[y]==dis[x]+e[i].val) {
                int k=dfs(y,std::min(e[i].dis,flow));
                e[i].dis-=k,e[i^1].dis+=k,res+=k,flow-=k,mcmf+=e[i].val*k;
            }
        }
        vis[x]=0;
        return res;
    }
}
using namespace Dinic_mcmf;
using namespace std;
int k,n,ans;
map<string,int> mm;
int match[601][601];

struct Nade {
    int x,y;
    string str;
}e1[100001],e2[100001];

int Dis(int x1,int y1,int x2,int y2) { return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); }

bool check(int X,int Y) {
    if (Dis(e1[X].x,e1[X].y,e2[Y].x,e2[Y].y)>k*k) return 0;
    double kk=(e1[X].y-e2[Y].y)/((e1[X].x-e2[Y].x)*1.0),bb=e1[X].y*1.0-e1[X].x*kk;
    int maxx=max(e1[X].x,e2[Y].x),minx=min(e1[X].x,e2[Y].x),maxy=max(e1[X].y,e2[Y].y),miny=min(e1[X].y,e2[Y].y);
    for (int i=1;i<=n;i++) {
        double ty=e1[i].x*kk+bb;
        if (i!=X and ty==e1[i].y*1.0 and (minx<=e1[i].x and e1[i].x<=maxx) and (miny<=e1[i].y and e1[i].y<=maxy)) return 0;
        ty=e2[i].x*kk+bb;
        if (i!=Y and ty==e2[i].y*1.0 and (minx<=e2[i].x and e2[i].x<=maxx) and (miny<=e2[i].y and e2[i].y<=maxy)) return 0;
    }
    return 1;
}

void Dfs(int x,int f) {
    for (int i=head[x];i;i=e[i].nxt) {
        int y=e[i].to;
        if (e[i].dis and y!=f) {
            // printf("%d %d %d %d\n",x,y,e[i].dis,e[i].val);
            // printf("%d %d %d %d\n",y,x,e[i^1].dis,e[i^1].val);
            Dfs(y,x);
        }  
    }
}

int main() {
    scanf("%d%d",&k,&n);
    t=2*n+1;
    for (int i=1;i<=n;i++) {
        scanf("%d%d",&e1[i].x,&e1[i].y);
        cin>>e1[i].str; mm[e1[i].str]=i;
        add(s,i,1,0),add(i,s,0,0);
    }
    for (int i=1;i<=n;i++) {
        scanf("%d%d",&e2[i].x,&e2[i].y);
        cin>>e2[i].str; mm[e2[i].str]=i+n;
        add(i+n,t,1,0),add(t,i+n,0,0);
    }
    string str1,str2; int mx;
    while (1) {
        cin>>str1;
        if (str1=="End") break;
        cin>>str2; scanf("%d",&mx);
        match[mm[str1]][mm[str2]]=match[mm[str2]][mm[str1]]=mx;
    }
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++) 
            if (check(i,j)) {
                if (!match[i][j+n]) match[i][j+n]=1;
                add(i,j+n,1,-match[i][j+n]),add(j+n,i,0,match[i][j+n]);
            }
    // Dfs(s,-1);
    while (SPFA(n)) ans+=dfs(s,INF);
    printf("%d\n",-mcmf);
    return 0;
}
/*
2
3
0 0 Adam
1 1 Jack
0 2 George
1 0 Victoria
0 1 Susan
1 2 Cathy
Adam Cathy 100
Susan George 20
George Cathy 40
Jack Susan 5
Cathy Jack 30
Victoria Jack 20
Adam Victoria 15
End
*/
2022/10/12 19:56
加载中...