码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2020-05-03 01:20:14      阅读:71      评论:0      收藏:0      [点我收藏+]

标签:flow   span   次数   long   建图   onclick   txt   height   inf   

技术图片

 

 

 思路

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

  通过限制好相邻点之间的流量,就能保证每个区间内保证不会有使用次数超过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 uint vint wint 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, 0sizeof(head));
    memset(pre, 0sizeof(pre));
    memset(inq, 0sizeof(inq));
    memset(dis, 0sizeof(dis));
    memset(e, 0sizeof(e));
    while(!q.empty()) {
        q.pop();
    }
    mincost = maxflow = 0;
    cnt = 1;
}

bool SPFA(int x)
{
    memset(inq, 0sizeof(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;
}

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

标签:flow   span   次数   long   建图   onclick   txt   height   inf   

原文地址:https://www.cnblogs.com/orangeko/p/12820125.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!