P3357 最長k可重線段集問題 網絡流

P3357 最長k可重線段集問題

題目描述

給定平面?x-O-yx?O?y?上?nn?個開線段組成的集合?II,和一個正整數?kk?。試設計一個算法,從開線段集合?II?中選取出開線段集合?S\subseteq IS?I?,使得在?xx?軸上的任何一點?pp,SS?中與直線?x=px=p?相交的開線段個數不超過?kk,且\sum\limits_{z\in S}|z|zS?z∣達到最大。這樣的集合?SS?稱為開線段集合?II?的最長?kk?可重線段集。\sum\limits_{z\in S}|z|zS?z∣?稱為最長?kk?可重線段集的長度。

對于任何開線段?zz,設其斷點坐標為?(x_0,y_0)(x0?,y0?)?和?(x_1,y_1)(x1?,y1?),則開線段?zz?的長度?|z|z∣?定義為:|z|=\lfloor\sqrt{(x_1-x_0)^2+(y_1-y_0)^2}\rfloorz=?(?

對于給定的開線段集合?II?和正整數?kk,計算開線段集合?II?的最長?kk?可重線段集的長度。

輸入輸出格式

輸入格式:

?

文件的第一 行有?22?個正整數?nn?和?kk,分別表示開線段的個數和開線段的可重疊數。

接下來的?nn?行,每行有?44?個整數,表示開線段的?22?個端點坐標。

?

輸出格式:

?

程序運行結束時,輸出計算出的最長?kk?可重線段集的長度。

?

輸入輸出樣例

輸入樣例#1:?復制
4 2
1 2 7 3
6 5 8 3
7 8 10 5
9 6 13 9 
輸出樣例#1:?復制
17

說明

1\leq n\leq5001n500

1 \leq k \leq 131k13

?

?

?

這個題目和之前的最長k可重區間集問題是一樣的,就是把平面上的線段投影到x軸,但是呢,有一個點有問題,就是要

特判兩條直線重合且垂直于x軸的這一種情況,具體是為什么呢,我也有點不明白為什么了,好像是會出現環的情況。

?

#include <cstdio>
#include <cstdlib>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>
#include <cmath>
#include <string>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5;
struct edge
{int u, v, c, f;ll cost;edge(int u, int v, int c, int f, ll cost) :u(u), v(v), c(c), f(f), cost(cost) {}
};
vector<edge>e;
vector<int>G[maxn];
int a[maxn];//找增廣路每個點的水流量
int p[maxn];//每次找增廣路反向記錄路徑
int d[maxn];//SPFA算法的最短路
int inq[maxn];//SPFA算法是否在隊列中
int s, t;
void init(int n)
{for (int i = 0; i <= n; i++)G[i].clear();e.clear();
}
void add(int u, int v, int c, ll cost)
{e.push_back(edge(u, v, c, 0, cost));e.push_back(edge(v, u, 0, 0, -cost));int m = e.size();G[u].push_back(m - 2);G[v].push_back(m - 1);
}
bool bellman(int s, int t, int& flow, long long & cost)
{memset(d, 0xef, sizeof(d));memset(inq, 0, sizeof(inq));d[s] = 0; inq[s] = 1;//源點s的距離設為0,標記入隊p[s] = 0; a[s] = INF;//源點流量為INF(和之前的最大流算法是一樣的)
queue<int>q;//Bellman算法和增廣路算法同步進行,沿著最短路拓展增廣路,得出的解一定是最小費用最大流
    q.push(s);while (!q.empty()){int u = q.front();q.pop();inq[u] = 0;//入隊列標記刪除for (int i = 0; i < G[u].size(); i++){edge & now = e[G[u][i]];int v = now.v;if (now.c > now.f && d[v] < d[u] + now.cost)//now.c > now.f表示這條路還未流滿(和最大流一樣)//d[v] > d[u] + e.cost Bellman 算法中邊的松弛
            {d[v] = d[u] + now.cost;//Bellman 算法邊的松弛p[v] = G[u][i];//反向記錄邊的編號a[v] = min(a[u], now.c - now.f);//到達v點的水量取決于邊剩余的容量和u點的水量if (!inq[v]) { q.push(v); inq[v] = 1; }//Bellman 算法入隊
            }}}if (d[t] < 0)return false;//找不到增廣路flow += a[t];//最大流的值,此函數引用flow這個值,最后可以直接求出flowcost += (long long)d[t] * (long long)a[t];//距離乘上到達匯點的流量就是費用for (int u = t; u != s; u = e[p[u]].u)//逆向存邊
    {e[p[u]].f += a[t];//正向邊加上流量e[p[u] ^ 1].f -= a[t];//反向邊減去流量 (和增廣路算法一樣)
    }return true;
}
int MaxcostMaxflow(int s, int t, long long & cost)
{cost = 0;int flow = 0;while (bellman(s, t, flow, cost));//由于Bellman函數用的是引用,所以只要一直調用就可以求出flow和costreturn flow;//返回最大流,cost引用可以直接返回最小費用
}struct node
{int xx1, yy1, xx2, yy2;ll cost;
}exa[maxn];
bool cmp(node a, node b)
{return a.xx1 < b.xx1;
}ll dis(int x, int y, int x1, int y1)
{return sqrt((x - x1) * 1ll * (x - x1) + (y - y1) * 1ll * (y - y1));
}int main()
{int n, m;cin >> n >> m;int s1 = 1;s = 0, t = 2 * n + 3;for (int i = 1; i <= n; i++){cin >> exa[i].xx1 >> exa[i].yy1 >> exa[i].xx2 >> exa[i].yy2;if (exa[i].xx1 > exa[i].xx2){swap(exa[i].xx1, exa[i].xx2);swap(exa[i].yy1, exa[i].yy2);}exa[i].cost = dis(exa[i].xx1, exa[i].yy1, exa[i].xx2, exa[i].yy2);}sort(exa + 1, exa + 1 + n, cmp);add(s, s1, m, 0);for (int i = 1; i <= n; i++){add(s1, 1 + 2 * i - 1, 1, 0);add(1 + 2 * i - 1, 1 + 2 * i, 1, exa[i].cost);add(1 + 2 * i, t, 1, 0);for (int j = 1; j < i; j++){if (exa[j].xx2 == exa[i].xx1&&exa[j].xx1 == exa[j].xx2&&exa[i].xx1==exa[i].xx2) continue;if (exa[j].xx2 <= exa[i].xx1) add(1 + 2 * j, 1 + 2 * i - 1, 1, 0);}}ll cost = 0;int ans = MaxcostMaxflow(s, t, cost);printf("%lld\n", cost);return 0;
}

?

轉載于:https://www.cnblogs.com/EchoZQN/p/10792823.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/386915.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/386915.shtml
英文地址,請注明出處:http://en.pswp.cn/news/386915.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

服務被人當肉雞了,叫一路賺錢 xig

網上看了一下&#xff0c;說有專門人研究服務 個人懷疑是阿里云內部人干的&#xff0c;因為買了服務器后&#xff0c;沒有安裝對外使用的地址性質的網站&#xff0c;IP開通了之后只有阿里的人知道&#xff0c;上面還有阿里云盾。 看了下進程地址&#xff0c;上面的啟動命令 x…

RUNOOB python練習題30 回文數

用來練手的python練習題 30。原題鏈接:python練習實例30 題干 : 一個5位數&#xff0c;判斷它是不是回文數。即12321是回文數&#xff0c;個位與萬位相同&#xff0c;十位與千位相同。 與上一個例題類似&#xff0c;判斷一個數是不是回文數&#xff0c;我們使用字符串類型更加…

高并發與負載均衡-keepalived-概念介紹

keepalived是用戶空間的程序&#xff0c;這個程序會同時在主的lvs和備用的lvs啟動 轉載于:https://www.cnblogs.com/LXL616/p/10793790.html

asp.net2.0跨域問題

什么叫跨域&#xff1f; 簡單理解就是不同服務器&#xff0c;不同域名之間的訪問。 1 如何設置asp.net web程序的跨域&#xff1f; 在web.config中添加如下代碼 1 <system.webServer> <httpProtocol> <customHeaders> <add name&qu…

RUNOOB python練習題31 根據已輸入的字符判斷星期幾

用來練手的python練習題31&#xff0c; 原題鏈接 : python練習實例31 題干 : 請輸入星期幾的第一個字母來判斷一下是星期幾&#xff0c;如果第一個字母一樣&#xff0c;則繼續判斷第二個字母。 一個條件語句練習題&#xff0c;非常簡單了可以說&#xff0c;就是把所有的條件都…

解決FTPClient上傳文件為空,顯示0字節

JAVA使用FTPClient上傳文件時總是為空&#xff0c;而使用FileZilla客戶端時卻不會。 后來查了下資料&#xff0c;FTP服務器有被動模式和主動模式。&#xff08;具體查另外資料&#xff09; 在JAVA中將FTPClient設置為被動模式即可解決問題。 import org.apache.commons.net.f…

軟件工程——結對編程第二次作業

目錄 1. 題目及要求2. 功能的設計3. GUI&#xff08;圖形用戶界面&#xff09;的設計4. 容錯機制的設計4.1 選擇運算符的容錯處理4.2 最大值和題目數輸入的容錯處理4.3 打開文件容錯處理4.4 打印的容錯處理5. 程序的運行效果6. 對領航員的評價7. 總結本次作業所開發的程序已上傳…

RUNOOB python練習題 32 列表的中括號符號小tips

用來練手的python練習題&#xff0c;原題鏈接: python練習實例32 題干: 按相反的順序輸出列表的值 拿到題目首先寫下如下代碼: a [1,2,3,4] for i in range(len(a)):print(a[len(a)-i-1])輸出結果如下: 使用一個簡單的循環就可以完成這個操作。但其實python有利用中括號操…

redis啟動后出現WARNING you have Transparent Huge Pages (THP) support enabled in your kernel問題...

問題描述&#xff1a;啟動redis后出現&#xff1a;WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command echo never > /sys/kernel/mm/trans…

Anaconda安裝第三方包(whl文件)

先說下環境 Anaconda 對應Python3.5的版本 win7,64位系統。 step1&#xff1a;下載whl文件 step2&#xff1a;打開‘Anaconda Command Prompt‘&#xff0c; 如下圖&#xff1a; step3&#xff1a;命令行窗口pip安裝&#xff0c;代碼如下&#xff1a; pip install 路徑whl…

RUNOOB python練習題33 使用join方法實現用逗號分隔列表

用來練手的python練習題&#xff0c;原題鏈接:python練習實例33 題干: 按逗號分隔列表 用逗號分隔列表&#xff0c;我們就想到了join方法。 str.join(sequence)可以用自定的str字符串分隔一個序列&#xff0c;這個序列可以是字符串&#xff0c;列表&#xff0c;元組&#xff…

Use Vim as a Python IDE

Use Vim as a Python IDE I love vim and often use it to write Python code. Here are some useful plugins and tools for building a delightful vim python environment, escpecially for Vim8: 我喜歡vim&#xff0c;經常用它來編寫Python代碼。以下是一些有用的插件和工…

sql2008“備份集中的數據庫備份與現有的xx數據庫不同”解決方法 因為是在另一臺電腦對同名數據庫做的備份,用常規方法還原,提示不是相同數據庫,不讓還原,在網上找到下面的方法解決了: 一、右擊系

sql2008“備份集中的數據庫備份與現有的xx數據庫不同”解決方法 因為是在另一臺電腦對同名數據庫做的備份&#xff0c;用常規方法還原&#xff0c;提示不是相同數據庫&#xff0c;不讓還原&#xff0c;在網上找到下面的方法解決了&#xff1a; 一、右擊系統數據庫master&…

RUNOOB python練習題 35 python print各色字體及背景

用來練手的python練習題&#xff0c;原題鏈接: python練習實例35 題干: 文本顏色設置 python中通過指令可以控制輸出的背景顏色&#xff0c;前景顏色&#xff0c;以及顯示方式。指令的語法如下: ’\033[顯示方式&#xff1b;前景色&#xff1b;背景色m 輸出字符 \033[0m’ 其…

ubuntu18.04 qemu環境搭建【學習筆記】

一、準備工具   1.1 安裝相關工具     sudo apt-get install qemu libncurses5-dev gcc-arm-linux-gnueabi build-essential 1.2 下載kernel(linux-4.0)與busybox(1.24)源碼 https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/ https://busybox.net/downloads/busy…

for else語句小tips : RUNOOB python練習題36

用來練手的python練習題&#xff0c;原題鏈接: python練習實例36 題干: 求100之內的素數 求某個范圍內的素數&#xff0c;和之前的一個例題其實是一樣的&#xff0c;上次的同類例題鏈接如下: python練習實例12 在實現題目要求時&#xff0c;這次用了for else語句&#xff0c…

Linux 下殺毒軟件 clamav 的安裝和使用

Linux 下殺毒軟件 clamav 的安裝和使用 安裝依賴&#xff1a; 1 2 3 yum install -y pcre* zlib zlib-devel libssl-devel libssl yum install -y openssl yum install -y epel-release openssl version 0.9.8 or higher 1. yum 安裝 clamav 安裝后會自動生成服務文件&#…

列表,元組和range

內容大綱 列表的初識列表的索引切片列表的增刪改查列表的嵌套元組的初識元組的簡單應用range 昨日內容回顧以及作業講解 int str boolstr 索引 s[x:y:z] 常用操作方法 upper lower startswith endswith split 分割:默認按照空格.將字符串分割成列表.可以知道分隔符 strip …

RUNOOB python練習題37 對一個序列的數進行排序

用來練手的Python練習題&#xff0c;原題鏈接: python練習實例37 題干: 對10個數進行排序 在我們使用Numpy模塊時&#xff0c;這個問題是非常簡單的&#xff0c;下面放出降序排列和升序排列的代碼: 升序排列 import numpy as npresult np.zeros(10) for i in range(result…

Linux服務器不停的向外發包,且CPU持續100%

服務器不停的向外發包&#xff0c;且CPU持續100%&#xff0c;遠程登錄后查看發現有一長度為10的隨機字符串進程&#xff0c;kill掉&#xff0c;會重新生成另外長度為10的字符串進程。刪除文件也會重復生成&#xff0c;非常痛苦。查閱crond相關日志&#xff0c;發現實際執行的內…