• POJ No.3680 Intervals


    2016-06-01 22:01:39

    题目链接: POJ No.3680 Intervals

    题目大意:

      给定N个带权区间,最多可以重复选一个点M次,求出一种选法使得所得权最大

    解法:

      费用流

      建模:

        区间的端点之间按照副权流量1连接,而每个点之间需要再连0权流量无穷作为跳过用

    注意的地方:

      十万个点肯定是不行的,看我unique离散化大法

      1 //Intervals (POJ No.3680)
      2 //费用流
      3 #include<stdio.h>
      4 #include<algorithm>
      5 #include<queue>
      6 using namespace std;
      7 const int maxn=410;
      8 int T,N,K;
      9 int hash[maxn];
     10 int a[maxn];
     11 int w[maxn];
     12 struct edge 
     13 {
     14     int to;
     15     int from;
     16     int cost;
     17     int flow;
     18     int next;
     19     edge(){}
     20     edge(int from,int to,int cost,int flow,int next):from(from),to(to),cost(cost),flow(flow),next(next){}
     21 };
     22 edge n[maxn*10];
     23 int cnt;
     24 int len;
     25 int now;
     26 int head[maxn];
     27 bool vis[maxn];
     28 int dist[maxn];
     29 int pre[maxn];
     30 queue <int> q;
     31 void insert(int x,int y,int z,int cost)
     32 {
     33     n[++cnt]=edge(x,y,cost,z,head[x]);
     34     head[x]=cnt;
     35     n[++cnt]=edge(y,x,-cost,0,head[y]);
     36     head[y]=cnt;
     37     return ;
     38 }
     39 void SPFA(int s,int t)
     40 {
     41     fill(dist,dist+maxn,100000);
     42     q.push(s);
     43     vis[s]=1;
     44     dist[s]=0;
     45     while(!q.empty())
     46     {
     47         now=q.front();
     48         q.pop();
     49         vis[now]=0;
     50         for(int i=head[now];i;i=n[i].next)
     51         {
     52             if(n[i].flow>0)
     53             {
     54                 if(dist[n[i].to]>dist[now]+n[i].cost)
     55                 {
     56                     dist[n[i].to]=dist[now]+n[i].cost;
     57                     pre[n[i].to]=i;
     58                     if(!vis[n[i].to])
     59                     {
     60                         vis[n[i].to]=1;
     61                         q.push(n[i].to);
     62                     }
     63                 }
     64             }
     65         }
     66     }
     67     for(int i=pre[t];i;i=pre[n[i].from])
     68     {
     69         n[i].flow--;
     70         n[i^1].flow++;
     71     }
     72     return ;
     73 }
     74 int Mincost_flow(int s,int t,int num)
     75 {
     76     int ans=0;
     77     while(num--)
     78     {
     79         SPFA(s,t);
     80         ans+=dist[t];
     81     }
     82     return -ans;
     83 }
     84 int main()
     85 {
     86     scanf("%d",&T);
     87     while(T--)
     88     {
     89         cnt=1;
     90         fill(head,head+maxn,0);
     91         scanf("%d %d",&N,&K);
     92         for(int i=1;i<=N;i++)
     93         {
     94             scanf("%d %d",&a[i*2-1],&a[i*2]);
     95             scanf("%d",&w[i]);
     96             hash[i*2-1]=a[i*2-1];
     97             hash[i*2]=a[i*2];
     98         }
     99         sort(hash+1,hash+2*N+1);
    100         len=unique(hash+1,hash+2*N+1)-hash-1;
    101         for(int i=1;i<=N*2;i++)
    102         {
    103             a[i]=lower_bound(hash+1,hash+len+1,a[i])-hash;
    104             if(!(i&1))insert(a[i-1],a[i],1,-w[i/2]);
    105         }
    106         for(int i=1;i<len;i++)insert(i,i+1,100000,0);
    107         insert(len,len+1,K,0);
    108         insert(0,1,K,0);
    109         printf("%d
    ",Mincost_flow(0,len+1,K));
    110     }
    111 }
  • 相关阅读:
    关于OutputStream的write方法FAQ(from bbs.csdn.net)
    【Java】对文件或文件夹进行重命名
    [复习] JAVA 遍历目录 (递归调用和非递归)
    [科普]关于文件头的那些事
    Intellij IDEA和EclipsE之间的的全面对比
    为什么43%前端开发者想学Vue.js
    Chrome调试ECMAScript之断点debug技巧大全!
    如何Vue-cli开始使用在Vue.js项目中启动TDD(测试驱动开发)
    toString() 和 (String) 以及 valueOf() 三者的对照关系[java]
    java打印和重写toString
  • 原文地址:https://www.cnblogs.com/Neptune-/p/5551267.html
Copyright © 2020-2023  润新知