POJ 3159 Candies 解题报告

24 篇文章 0 订阅
11 篇文章 0 订阅

Question Link

差分约束系统对应的最短路。
题意:

n个人,m个约束,约束是,由,A,B,C,三个数字组成。B比A多出来的糖果不超过C个,问,n号人最多比1号人多几个糖果?

解法:

对应最短路模型,在松弛完最短路后则变为 d[v] <= d[u] + w ,转化为 d[v] - d[u] <= w,这个和上面的 B - A <= C 是相同的模式 , 因此建图的时候只需要单向图,以1为起点,n为终点跑dijkstra即可。

与最短路模型的差异

每次贪心取得最大的约束,这样才能使得最后n到1的约束最大。

对应代码差异
struct qnode{
	int v,w; 
	qnode(int _v=0,int _c=0):v(_v),w(_c){}
	bool operator < ( const qnode &r)const {
		return w > r.w;
	}
};
AC code
#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define mset(var,val)	 memset(var,val,sizeof(var))
#define LL long long 
#define eps 0.000001
#define inf 0x7f7f7f7f
#define llinf 1e18
#define exp 0.000001
#define pai 3.141592654
#define random(x)   rand()%(x)
#define lowbit(x)   x&(-x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=(x<<3)+(x<<1)+a-'0'; a=getchar();}return x*y;
}
#define N 30010
#define M 150010
struct edge{
	int u,v,w,nx; 
}e[M];int tot,hea[N];bool inq[N];int n,m,dis[N];
struct qnode{
	int v,w; 
	qnode(int _v=0,int _c=0):v(_v),w(_c){}
	bool operator < ( const qnode &r)const {
		return w > r.w;
	}
};
inline void addead(int u,int v,int w){
	++tot; 
	e[tot].u = u; e[tot].v = v; e[tot].w = w; e[tot].nx = hea[u]; hea[u] = tot; 
}
void init(){
	mset(hea,0);
	mset(inq,0);
	mset(dis,0x3f);
	tot = 0; 
}
void dijkstra(){
	priority_queue<qnode>q; 
	while ( !q.empty() )	q.pop();
	q.push( qnode(1,0) );
//	inq[ 1 ] = 1; 
	dis[ 1 ] = 0; 
	while ( !q.empty() ){
		qnode tem = q.top(); 
		q.pop();
		int u = tem.v;
		if ( inq[ u ] ) 	continue; 
		inq[ u ] = 1; 
		for (int i = hea[u]; i ; i = e[i].nx){
			if ( dis[ e[i].v ] > dis[ u ] + e[i].w ){
				dis[ e[i].v ] = dis[ u ] + e[i].w ; 
				if ( inq[ e[i].v ] == 0 ){
//					inq[i] = 1; 
					q.push( qnode( e[i].v,dis[ e[i].v ]) );
				}
			}
		}
	}
}
int main()
{
//	freopen("1.txt","r",stdin);
	srand((int)time(0));
//	std::ios::sync_with_stdio(false); 
	while ( scanf("%d%d",&n,&m) != EOF ){
		init();
		rep(i,1,m){
			int u,v,w; 
			u = read(); v = read(); w = read();
			addead(u,v,w);
		}
		dijkstra();
		printf("%d\n",dis[n]);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值