題目鏈結
輸入最多500個點對,即離散化後最多有1000個座標。
對離散化後的座標建圖。
方法一:將座標從小到大連邊,乙個點與它後面相鄰的點建一條邊(流量為inf,花費為0),點對的左端點與右端點建一條邊(流量為1,花費為(-區間長度)),s與第乙個點建一條邊(流量為k,花費為0),最後乙個點與t建一條邊(流量為k,花費為0)
方法二:s與s'之間建一條邊(流量為k,花費為0),s'與各區間左端點之間建一條邊(流量為1,花費為0),區間左端點向本區間的右端點建一條邊(流量為1,花費為(-區間長度)),區間右端點與比它大的區間左端點建邊(流量為1,花費為0),各區間右端點與t建一條邊(流量為1,花費為0)
方法一**:
#include using namespace std;
#define ll long long
const int maxn = 10010;
const int maxm = 100010;
const int inf = 0x3f3f3f3f;
struct edge e[maxm];
int head[maxn], tot;
int pre[maxn], dis[maxn];
bool vis[maxn];
int n;
void init(int n)
void addedge(int u, int v, int cap, int cost)
bool spfa(int s, int t)
dis[s] = 0;
vis[s] = true;
q.push_front(s);
while (!q.empty()) else q.push_back(v);}}
}}
return pre[t] != -1;
}int mcfc(int s, int t, int &cost)
}for (int i = pre[t]; i != -1; i = pre[e[i ^ 1].to])
flow += minn;
}return flow;
}vectorx;
int a[maxn], b[maxn], c[maxn];
int main()
//離散化
sort(x.begin(), x.end());
x.erase(unique(x.begin(), x.end()), x.end());
int s = 0, t = x.size() - 1;
for (int i = 0; i < t; i++)
addedge(i, i + 1, inf, 0);
for (int i = 0; i < n; i++)
int ans;
s = x.size(), t = s + 1;
addedge(s, 0, k, 0);
addedge(x.size() - 1, t, k, 0);
mcfc(s, t, ans);
cout << -ans << endl;
return 0;
}
方法二**:
//其餘**與上面相同
int main()
//離散化
sort(x.begin(), x.end());
x.erase(unique(x.begin(), x.end()), x.end());
int s = x.size(), t = s + 2, s1 = s + 1;
addedge(s, s1, k, 0);
for (int i = 0; i < n; i++)
}int ans;
mcfc(s, t, ans);
cout << -ans << endl;
return 0;
}
網路流 P3358 最長k可重區間集問題
對於給定的開區間集合 i 和正整數 k,計算開區間集合 i 的最長 k可重區間集的長度。輸入格式 的第 1 行有 2 個正整數 n和 k,分別表示開區間的個數和開區間的可重迭數。接下來的 n行,每行有 2 個整數,表示開區間的左右端點座標。輸出格式 將計算出的最長 k可重區間集的長度輸出 輸入樣例 ...
洛谷P3358 最長k可重區間集問題 費用流
對於給定的開區間集合 i 和正整數 k,計算開區間集合 i 的最長 k可重區間集的長度。輸入格式 的第 1 行有 2 個正整數 n和 k,分別表示開區間的個數和開區間的可重迭數。接下來的 n行,每行有 2 個整數,表示開區間的左右端點座標。輸出格式 將計算出的最長 k可重區間集的長度輸出 輸入樣例 ...
洛谷3358 最長k可重區間集問題(費用流)
點此看題面 說實話,這種題型是我長久以來一直很想知道怎麼做的,果然網路流二十四題真的是經典好題。我們可以把原題面改成選擇 k 次,每次可以選擇任意個不相交的區間。為了實現選 k 次,我們需要從超級源向第乙個點連一條容量為 k 價值為 0 的邊。然後,我們從座標軸上每個點向相鄰的下乙個點 最後乙個點向...