差分约束系统+输出路径(I - Advertisement POJ - 1752 )

题目链接:https://cn.vjudge.net/contest/276233#problem/I

题目大意:输入k和n,然后输入n行,每一次输入两个数,代表开端和结尾,如果这个区间内点的个数大于等于k,那么就要求这个区间至少有k个点被圈起来,如果这个区间内的点的个数小于k,就要求这个区间内的点全部被包括起来,然后问你最多需要多少点?

具体思路:正常的建图方式,为了使得路径输出的时候,方便利用数组,我们可以直接在原来的基础上加上10000,这样的化就可以用数组记录到底有还是没有了。路径输出的时候判断条件(dis[i+1]-dis[i]>=1).

AC代码:

  1 #include<iostream>
  2 #include<cstring>
  3 #include<stack>
  4 #include<iomanip>
  5 #include<cmath>
  6 #include<queue>
  7 #include<algorithm>
  8 #include<stdio.h>
  9 using namespace std;
 10 # define ll long long
 11 # define inf 0x3f3f3f3f
 12 const int maxn = 30000+100;
 13 const int maxedge = 5e6+10;
 14 struct node
 15 {
 16     int to;
 17     int nex;
 18     int cost;
 19 } edge[maxedge];
 20 vector<int>w;
 21 int head[maxn],pre[maxn],dis[maxn],vis[maxn];
 22 int num;
 23 void init()
 24 {
 25     num=0;
 26     for(int i=0; i<=maxn; i++)
 27     {
 28         pre[i]=-inf;
 29         dis[i]=inf;
 30         head[i]=-1;
 31     }
 32 }
 33 void addedge(int fr,int to,int cost)
 34 {
 35     edge[num].to=to;
 36     edge[num].cost=cost;
 37     edge[num].nex=head[fr];
 38     head[fr]=num++;
 39 }
 40 int spfa(int st,int ed)
 41 {
 42     queue<int>q;
 43     vis[st]=1;
 44     dis[st]=0;
 45     q.push(st);
 46     while(!q.empty())
 47     {
 48         int tmp=q.front();
 49         q.pop();
 50         vis[tmp]=0;
 51         for(int i=head[tmp]; i!=-1; i=edge[i].nex)
 52         {
 53             int u=edge[i].to;
 54             if(dis[u]>dis[tmp]+edge[i].cost)
 55             {
 56                 dis[u]=dis[tmp]+edge[i].cost;
 57                 pre[u]=tmp;
 58                 if(vis[u])
 59                     continue;
 60                 vis[u]=1;
 61                 q.push(u);
 62             }
 63         }
 64     }
 65     return dis[ed];
 66 }
 67 int main()
 68 {
 69     int k,n;
 70     scanf("%d %d",&k,&n);
 71     int u,v;
 72     init();
 73     int minx=inf,maxy=0;
 74     for(int i=1; i<=n; i++)
 75     {
 76         scanf("%d %d",&u,&v);
 77         if(u>v)
 78             swap(u,v);
 79         u+=10000;
 80         v+=10000;
 81         int len=v-u+1;
 82         addedge(v,u-1,len);
 83         addedge(u-1,v,-min(len,k));
 84         minx=min(minx,u-1);
 85         maxy=max(maxy,v);
 86     }
 87     for(int i=minx; i<maxy; i++)
 88     {
 89        addedge(minx-1,i,0);
 90         addedge(i,i+1,0);
 91         addedge(i+1,i,1);
 92     }
 93     addedge(minx,maxy,0);
 94     int ans=spfa(minx,maxy);
 95     for(int i=minx+1; i<=maxy; i++)
 96     {
 97         if(dis[i]!=dis[i-1])
 98         {
 99             w.push_back(i);
100         }
101     }
102     int len=w.size();
103     printf("%d\n",len);
104     sort(w.begin(),w.end());
105     for(int i=0; i<len; i++)
106     {
107         cout<<w[i]-10000<<endl;
108     }
109 
110     return 0;
111 }
112  

 

posted @ 2018-12-20 22:18  Let_Life_Stop  阅读(201)  评论(0编辑  收藏  举报