您的位置:首页 > 其它

poj1752 - Advertisement

2012-09-14 19:12 369 查看
                                 
想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
                                 
转载请注明出处:http://blog.csdn.net/wangjian8006

题目大意:有n个人在一条路上跑步,广告商准备在这条路上设置广告牌,假设这条路上每一个点有一个广告牌

现在已知这n个人从Ai开始跑,到Bi结束,那么他可以看到max(Ai,Bi)-min(Ai,Bi)-1的广告牌数,现在广告商

需要每个人都要看到k个广告牌,这样,n个人过去了,问总的广告牌数和哪些广告牌是需要留下的

 

解题思路:差分约束:

从题目意思可以得到以下这些约束:

设a=max(Ai,Bi);

b=min(Ai,Bi)-1;

设c=a-b;

如果a-b>=k

那么得到一个约束a-b<=k

得到一条有向边<b,a>==k

如果a-b<k

则这个人只能看到a-b的广告牌

所以得到第二个约束a-b=c

变换一下就是

a-b<=c

a-b>=c---->b-a<=-c

得到两条边:

<b,a>===c

<a,b>===-c

当然还有一个大的约束条件是:

对于任意一点有0<=d[i+1]-d[i]<=1

即相邻两点的广告牌大于等于0小于等于1

  最后输出哪个广告牌存在时,得到d[i]-d[i-1]==1,即i-1到i有一块广告牌输出i

  总的广告牌数存在在d[end]

 

 

/*
Memory 956K
Time  500MS
*/
#include <iostream>
#include <queue>
using namespace std;
#define MAXV 20000
#define INF 0xfffffff
#define min(a,b) (a>b?b:a)
#define max(a,b) (a<b?b:a)

typedef struct{
int t,w,next;
}Edge;

Edge edge[8*MAXV];
int k,n;
int d[2*MAXV];
bool vis[2*MAXV];
int headlist[2*MAXV],edge_sum;
int start,end;

void swap(int &a,int &b){
int tmp;
tmp=a;a=b;b=tmp;
}

void addedge(int s,int t,int w){
edge[edge_sum].t=t;
edge[edge_sum].w=w;
edge[edge_sum].next=headlist[s];
headlist[s]=edge_sum++;
}

void spfa(){
int i,v,t;
queue <int>q;
for(i=start;i<=end;i++){
d[i]=-INF;
vis[i]=0;
}

d[start]=0;
vis[start]=1;
q.push(start);
while(!q.empty()){
v=q.front();q.pop();
vis[v]=0;

for(i=headlist[v];i!=-1;i=edge[i].next){
t=edge[i].t;
if(d[v]+edge[i].w>d[t]){
d[t]=d[v]+edge[i].w;
if(!vis[t]){
q.push(t);
vis[t]=1;
}
}
}
}
}

int main(){
int i,a,b,c;
while(~scanf("%d%d",&k,&n)){
edge_sum=0;start=INF;end=-1;
memset(headlist,-1,sizeof(headlist));
for(i=0;i<n;i++){
scanf("%d%d",&a,&b);
if(a>b) swap(a,b);
a+=MAXV-1;
b+=MAXV;
start=min(start,a);
end=max(end,b);
c=b-a;
if(c<k){
addedge(a,b,c);
addedge(b,a,-c);
}else
addedge(a,b,k);
}

for(i=start;i<=end;i++){		//相邻两点的约束条件
addedge(i,i+1,0);
addedge(i+1,i,-1);
}

spfa();

printf("%d\n",d[end]);
for(i=start;i<=end;i++){
if(d[i]-d[i-1]==1)
printf("%d\n",i-MAXV);
}
}
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bi struct ini c