网络流求救!!! P3357Wa2
  • 板块题目总版
  • 楼主Lidaban
  • 当前回复0
  • 已保存回复0
  • 发布时间2021/7/2 21:43
  • 上次更新2023/11/4 18:55:31
查看原帖
网络流求救!!! P3357Wa2
275556
Lidaban楼主2021/7/2 21:43

求告诉孩子2是什么数据QAQ 代码写的不好,不建议阅读QAQ

#include <bits/stdc++.h>
using namespace std;
//到77 行都是板子 不用看!!!
const int Mv = 1e6 + 5;
const int Me = 1e6 + 5;
#define ll long long
int head[Mv],pv[Mv],pe[Mv],vis[Mv];
ll h[Mv],dis[Mv];
int n,m,cnt = 1,S,T;
typedef pair <ll,ll> pll;
const ll inf = 1LL << 50;
struct node{
    int to,nxt;
    ll cost,flow;
}Edge[Me];

void Adde(int a,int b,ll flow,ll cost){
    Edge[++cnt].nxt = head[a];
    Edge[cnt].to = b;
    Edge[cnt].cost = cost;
    Edge[cnt].flow = flow;
    head[a] = cnt;
    Edge[++cnt].nxt = head[b];
    Edge[cnt].to = a;
    Edge[cnt].cost = -cost;
    Edge[cnt].flow = 0;
    head[b] = cnt;
}
int q[Me];
pll spfa(){
    ll flow = 0,cost = 0;
    while(1){
        for(int i = 0;i <= T;i ++) dis[i] = inf,vis[i] = 0;
        int l,r;
        int v,u;
        l = r = 1;
        q[l] = S;
        dis[S] = 0;
        vis[S] = 1;
        while(l <= r){
            u = q[l ++];
            vis[u] = 0;
            for(int p = head[u];p;p = Edge[p].nxt){
                v = Edge[p].to;
                if(dis[v] > dis[u] + Edge[p].cost && Edge[p].flow > 0){
                    dis[v] = dis[u] + Edge[p].cost;
                    pe[v] = p;
                    pv[v] = u;
                    if(!vis[v]) q[++r] = v;
                }
            }
        }
        if(dis[T] == inf) break;
        ll newflow = inf;
        for(int p = T;p != S;p = pv[p])
            newflow = min(newflow,Edge[pe[p]].flow);
        flow += newflow;
        cost += newflow * dis[T];
        for(int p = T;p != S;p = pv[p])
            Edge[pe[p]].flow -= newflow,
            Edge[pe[p] ^ 1].flow += newflow;
    }
    return pll(flow,cost);
}
struct {
    ll x,y,xx,yy;
    ll cost;
    void cal(){
        cost = floor(sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy)));
    }
}pos[Mv];





//判断是否相交
bool check(int a,int b,int c,int d){
    if(c >= a && c <= b) return 1;
    if(d >= a && d <= b) return 1;
    if(a >= c && a <= d) return 1;
    if(b >= c && b <= d) return 1;
    return 0;
}
int ins[Mv];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++){
        scanf("%lld%lld%lld%lld",&pos[i].x,&pos[i].y,&pos[i].xx,&pos[i].yy);
        pos[i].cal();
        if(pos[i].x == pos[i].xx) pos[i].xx ++;//如果垂直 则 右侧的x值 + 1
        if(pos[i].x > pos[i].xx){
            swap(pos[i].x,pos[i].xx);
            swap(pos[i].y,pos[i].yy);
        }
    }
    S = 0,T = 2 * n + 2;
    int ss = 2 * n + 1;// ss 是s撇,次汇点
    for(int i = 1;i <= n;i ++){
        for(int j = i + 1;j <= n;j ++){
            //开区间 闭区 右 -1 转换成闭区间
            if(!check(pos[i].x,pos[i].xx - 1,pos[j].x,pos[j].xx - 1)){
                if(pos[i].x > pos[j].x){
                    swap(i,j);
                    Adde(i + n,j,inf,0);
                    swap(i,j);
                }else Adde(i + n,j,inf,0);
            }
        }
    }
    Adde(S,ss,m,0);
    for(int i = 1;i <= n;i ++){
        if(ins[i]) continue;
        Adde(ss,i,1,0);
        Adde(i,i + n,1,-pos[i].cost);
        Adde(i + n,T,1,0);
    }
    //puts("1");
    printf("%lld\n",-spfa().second);
    return 0;
}

2021/7/2 21:43
加载中...