ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

最长k可重区间集问题【网络流24题】

2020-05-02 23:00:54  阅读:249  来源: 互联网

标签:24 pre 可重 temp int memset maxn sizeof 最长


 

 

 思路

  由要求线段的长度,很容易想到应该把问题转化成求费用流。

  通过限制好相邻点之间的流量,就能保证每个区间内保证不会有使用次数超过x次的点。

  然后再把区间作为主要要求的目标,把一个区间看作一个有点权的点连在图中。

  因为区间只能使用一次,且为了计算长度,我们让这个区间的费用为 -len。

  这样跑MCMF所得出的mincost就是跑满图时得到的最大区间长度。

  但是由于本题数据给出的区间范围相当大

  正常的建图只能过掉前六个点

  考虑到 n 很小,说明区间大时不需要用的点很多

  所以这些点之间连边与否是完全不影响整张图的流量的

  这时考虑离散化,就能在找残量网络和更新最大费用时减少毫不相干的时空支出

  

CODE

 

  1 #include <bits/stdc++.h>
  2 #define dbg(x) cout << #x << "=" << x << endl
  3 #define eps 1e-8
  4 #define pi acos(-1.0)
  5 
  6 using namespace std;
  7 typedef long long LL;
  8 const int maxn = 1e5 +7;
  9 const int inf  = 0x3f3f3f3f;
 10 
 11 int n, m, s, t;
 12 int head[maxn],pre[maxn],inq[maxn],dis[maxn];
 13 int a[maxn];
 14 int cnt = 1;
 15 int path[2][maxn];
 16 int mincost = 0, maxflow = 0;
 17 struct edge {
 18     int u,to,nxt,w,c;
 19 }e[maxn << 1];
 20 int tot[5];
 21 
 22 template<class T>inline void read(T &res)
 23 {
 24     char c;T flag=1;
 25     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
 26     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
 27 }
 28 
 29 inline void BuildGraph(int u, int v, int w, int cost)
 30 {
 31     e[++cnt] = (edge){u, v, head[u], w,  cost}, head[u] = cnt;
 32     e[++cnt] = (edge){v, u, head[v], 0, -cost}, head[v] = cnt;///反向边
 33 }
 34 
 35 queue<int> q;
 36 
 37 inline void init() {
 38     memset(head, 0, sizeof(head));
 39     memset(pre, 0, sizeof(pre));
 40     memset(inq, 0, sizeof(inq));
 41     memset(dis, 0, sizeof(dis));
 42     memset(e, 0, sizeof(e));
 43     while(!q.empty()) {
 44         q.pop();
 45     }
 46     mincost = maxflow = 0;
 47     cnt = 1;
 48 }
 49 
 50 bool SPFA(int x)
 51 {
 52     memset(inq, 0, sizeof(inq));
 53     for(int i = s; i <= t; i++) {
 54         dis[i] = inf;
 55     }
 56     q.push(x);
 57     dis[x] = 0;
 58     inq[x] = 1;
 59     while(!q.empty()) {
 60         int u = q.front();
 61         q.pop();
 62         inq[u] = 0;
 63         for(int i = head[u]; i; i = e[i].nxt) {
 64             int v = e[i].to, w = e[i].c;
 65             if(e[i].w > 0) {
 66                 if(dis[u] + w < dis[v]) {
 67                     dis[v] = dis[u] + w;
 68                     pre[v] = i;
 69                     if(!inq[v]) {
 70                         q.push(v);
 71                         inq[v] = 1;
 72                     }
 73                 }
 74             }
 75         }
 76     }
 77     if(dis[t] == inf)
 78         return 0;
 79     return 1;
 80 }
 81 
 82 void MCMF()
 83 {
 84     while(SPFA(s)) {
 85         int temp = inf;
 86         for(int i = pre[t]; i; i = pre[e[i].u]) {
 87             temp = min(temp, e[i].w);
 88         }
 89         for(int i = pre[t]; i; i = pre[e[i].u]) {
 90             e[i].w   -= temp;
 91             e[i^1].w += temp;
 92             mincost += e[i].c * temp;
 93             //printf("e[%d].c:%d\n",i, e[i].c);
 94             //printf("ans:%d\n",ans);
 95         }
 96         //maxflow += temp;
 97     }
 98 }
 99 
100 int k;
101 int l[maxn], r[maxn];
102 int ls[maxn], lss[maxn];
103 int totls, totlss;
104 int len[maxn];
105 
106 void Unique() {
107     for ( int i = 1; i <= n; ++i ) {
108         for ( int j = 1; j <= totlss; ++j ) {
109             if(l[i] == lss[j]) {
110                 l[i] = j;
111             }
112             if(r[i] == lss[j]) {
113                 r[i] = j;
114             }
115         }
116     }
117 }
118 
119 int main()
120 {
121     //freopen("data.txt", "r", stdin);
122     read(n); read(k);
123     init();
124     for ( int i = 1; i <= n; ++i ) {
125         read(l[i]); read(r[i]);
126         ls[++totls] = l[i];
127         ls[++totls] = r[i];
128         len[i] = r[i] - l[i];
129     }
130     sort(ls + 1, ls + 1 + totls);
131     for ( int i = 1; i <= totls; ++i ) {
132         if(ls[i] == ls[i-1])
133             continue;
134         lss[++totlss] = ls[i];
135     }
136     Unique();
137     s = 0;
138     for ( int i = 1; i <= n; ++i ) {
139         t = max(t, r[i]);
140         BuildGraph(l[i], r[i], 1, -len[i]);
141     }
142     for ( int i = 0; i <= t; ++i ) {
143         BuildGraph(i, i + 1, k, 0);
144     }
145     ++t;
146     MCMF();
147     cout << -mincost << endl;
148     return 0;
149 }
View Code

 

 

 

#include <bits/stdc++.h> #define dbg(x) cout << #x << "=" << x << endl #define eps 1e-8 #define pi acos(-1.0)
using namespace std; typedef long long LL; const int maxn = 1e5 +7; const int inf  = 0x3f3f3f3f;
int n, m, s, t; int head[maxn],pre[maxn],inq[maxn],dis[maxn]; int a[maxn]; int cnt = 1; int path[2][maxn]; int mincost = 0, maxflow = 0; struct edge {     int u,to,nxt,w,c; }e[maxn << 1]; int tot[5];
template<class T>inline void read(T &res) {     char c;T flag=1;     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; }
inline void BuildGraph(int u, int v, int w, int cost) {     e[++cnt] = (edge){u, v, head[u], w,  cost}, head[u] = cnt;     e[++cnt] = (edge){v, u, head[v], 0, -cost}, head[v] = cnt;///反向边 }
queue<int> q;
inline void init() {     memset(head, 0, sizeof(head));     memset(pre, 0, sizeof(pre));     memset(inq, 0, sizeof(inq));     memset(dis, 0, sizeof(dis));     memset(e, 0, sizeof(e));     while(!q.empty()) {         q.pop();     }     mincost = maxflow = 0;     cnt = 1; }
bool SPFA(int x) {     memset(inq, 0, sizeof(inq));     for(int i = s; i <= t; i++) {         dis[i] = inf;     }     q.push(x);     dis[x] = 0;     inq[x] = 1;     while(!q.empty()) {         int u = q.front();         q.pop();         inq[u] = 0;         for(int i = head[u]; i; i = e[i].nxt) {             int v = e[i].to, w = e[i].c;             if(e[i].w > 0) {                 if(dis[u] + w < dis[v]) {                     dis[v] = dis[u] + w;                     pre[v] = i;                     if(!inq[v]) {                         q.push(v);                         inq[v] = 1;                     }                 }             }         }     }     if(dis[t] == inf)         return 0;     return 1; }
void MCMF() {     while(SPFA(s)) {         int temp = inf;         for(int i = pre[t]; i; i = pre[e[i].u]) {             temp = min(temp, e[i].w);         }         for(int i = pre[t]; i; i = pre[e[i].u]) {             e[i].w   -= temp;             e[i^1].w += temp;             mincost += e[i].c * temp;             //printf("e[%d].c:%d\n",i, e[i].c);             //printf("ans:%d\n",ans);         }         //maxflow += temp;     } }
int k; int l[maxn], r[maxn]; int ls[maxn], lss[maxn]; int totls, totlss; int len[maxn];
void Unique() {     for ( int i = 1; i <= n; ++i ) {         for ( int j = 1; j <= totlss; ++j ) {             if(l[i] == lss[j]) {                 l[i] = j;             }             if(r[i] == lss[j]) {                 r[i] = j;             }         }     } }
int main() {     //freopen("data.txt", "r", stdin);     read(n); read(k);     init();     for ( int i = 1; i <= n; ++i ) {         read(l[i]); read(r[i]);         ls[++totls] = l[i];         ls[++totls] = r[i];         len[i] = r[i] - l[i];     }     sort(ls + 1, ls + 1 + totls);     for ( int i = 1; i <= totls; ++i ) {         if(ls[i] == ls[i-1])             continue;         lss[++totlss] = ls[i];     }     Unique();     s = 0;     for ( int i = 1; i <= n; ++i ) {         t = max(t, r[i]);         BuildGraph(l[i], r[i], 1, -len[i]);     }     for ( int i = 0; i <= t; ++i ) {         BuildGraph(i, i + 1, k, 0);     }     ++t;     MCMF();     cout << -mincost << endl;     return 0; }

标签:24,pre,可重,temp,int,memset,maxn,sizeof,最长
来源: https://www.cnblogs.com/orangeko/p/12820125.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有