转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4303365.html ---by 墨染之樱花
题目链接:http://poj.org/problem?id=1201
题目描述:给出n个整数三元组(x,y,c),求一个整数集合Z,使其对每个前述三元组都满足在x与y之间(闭区间)的数的个数至少为c,求这个整数集合Z的最少有几个数
思路:利用差分约束系统求解。构造数列a1a2a3...an(其中ai只能为0或1,0表示i不在Z中,1表示i在Z中)Sk=a1+a2+...+ak表示前k项的和,同时显然也就是指Z里面共有几个1到k中的数。那么根据每一个三元组,就可以列出不等式Sy+1-Sx>=c,在差分约束系统中可变为y+1指向x的一条权值为-c的边,除此之外还有隐含条件0<=ai<=1,可列出不等式0<=Si+1-Si<=1,构造完成以后用SPFA求解V到0的最短路即可(其中V取所有x,y里面的最大值)。
比较坑的是这道题卡STL,手写邻接表保平安吧。还有奇怪的一点是这题无论是在POJ还是在HDU上双端队列优化的SPFA竟然都比没优化的还慢,不明白。。。
#include <iostream> #include <ios> #include <iomanip> #include <functional> #include <algorithm> #include <vector> #include <sstream> #include <list> #include <queue> #include <deque> #include <stack> #include <string> #include <set> #include <map> #include <cstdio> #include <cstdlib> #include <cctype> #include <cmath> #include <cstring> #include <climits> using namespace std; #define XINF INT_MAX #define INF 1<<30 #define MAXN 50000+10 #define eps 1e-10 #define zero(a) fabs(a)<eps #define sqr(a) ((a)*(a)) #define MP(X,Y) make_pair(X,Y) #define PB(X) push_back(X) #define PF(X) push_front(X) #define REP(X,N) for(int X=0;X<N;X++) #define REP2(X,L,R) for(int X=L;X<=R;X++) #define DEP(X,R,L) for(int X=R;X>=L;X--) #define CLR(A,X) memset(A,X,sizeof(A)) #define IT iterator #define PI acos(-1.0) #define test puts("OK"); #define _ ios_base::sync_with_stdio(0);cin.tie(0); typedef long long ll; typedef pair<int,int> PII; typedef priority_queue<int,vector<int>,greater<int> > PQI; typedef vector<PII> VII; typedef vector<int> VI; #define X first #define Y second struct edge { int to,co,next; edge(int _to=0,int _co=0,int _next=0){to=_to;co=_co;next=_next;} } edges[150000+10]; int head[MAXN]={0}; int V; int d[MAXN]; bool inq[MAXN]={0}; inline void addedge(int x,int y,int c,int &cnt) { edge e(y,c,0); edges[cnt]=e; edges[cnt].next=head[x]; head[x]=cnt; cnt++; } void SPFA(int s) { REP(i,V) d[i]=INF; queue<int> Q; Q.push(s); d[s]=0;inq[s]=1; while(!Q.empty()) { int u=Q.front();Q.pop();inq[u]=0; for(int j=head[u];j;j=edges[j].next) { int v=edges[j].to,cost=edges[j].co; if(d[v]>d[u]+cost) { d[v]=d[u]+cost; if(!inq[v]) { inq[v]=1; Q.push(v); } } } } } int main() {_ int n; scanf("%d",&n); V=0; int cnt=1; REP(i,n) { int x,y,c; scanf("%d%d%d",&x,&y,&c); x++;y+=2; //为了使0作为终点,所以让节点的下标都从1开始 if(y>V) V=y; addedge(y,x,-c,cnt); } for(int i=0;i<V;i++) { addedge(i,i+1,1,cnt); addedge(i+1,i,0,cnt); } SPFA(V); printf("%d\n",-d[0]); return 0; }
时间: 2024-09-30 09:50:52