POJ 1201
d[i]表示在[0,i]這個區間內一共選了d[i]個數
對于每個為[ai,bi]的區間,你必須在這個區間上至少取ci個不同的整數,用d[i]如何表示?
d[ bi ]-d[ ai-1 ] >= ci
Edge:(ai-1 -> bi) val = ci
另外:
0<=d[i]-d[i-1]<=1
對應邊Edge:(i-1,i) val=0? Edge(i,i-1) val=-1
可以令d[maxa-1]=0
那么,最后d[maxb]-d[maxa-1] 就是最后的答案。
?
#include <cstdio>
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 200001
int first[N],e,d[N], w[N],v[N],next[N];
int n,m;
bool inq[N];
void init(){
?? ?e=0;
?? ?memset(first,-1,sizeof(first));
?? ?memset(inq,0,sizeof(inq));
}
void addedge(int a,int b,int x){
?? ?v[e]=b;
?? ?next[e]=first[a];
?? ?w[e]=x;
?? ?first[a]=e++;
}
void SPFA(int min1,int max1){
?? ?for(int i=min1+1;i<=max1;i++){
?? ??? ?d[i]=-INF;
?? ?}
?? ?d[min1]=0;
?? ?queue<int> q;
?? ?q.push(min1);
??? inq[min1] = 1;
??? while(!q.empty()){
??????? int ith = q.front();
??????? q.pop();
??????? inq[ith] = 0;
??????? for(int i = first[ith];i != -1;i = next[i]){
??????????? if(d[v[i]]<d[ith]+w[i]){
??????????????? d[v[i]] = d[ith]+w[i];
??????????????? if(!inq[v[i]]){
??????????????????? q.push(v[i]);
??????????????????? inq[v[i]] = 1;
??????????????? }
??????????? }
??????? }
??? }
}
int main(){
?? // freopen("test.txt","r",stdin);
?? ?int t,a,b,x;
?? ??? ?scanf("%d",&t);
?? ??? ?init();
?? ??? ?int s=1<<30,e=0;
?? ??? ?for(int i=0;i<t;i++){
?? ??? ??? ?scanf("%d%d%d",&a,&b,&x);
?? ??? ??? ?addedge(a-1,b,x);
?? ??? ??? ?if(a-1<s)s=a-1;
?? ??? ??? ?if(b>e)e=b;
?? ??? ?}
?? ??? ?for(int i=s;i<e;i++){
?? ??? ??? ?addedge(i,i+1,0);
?? ??? ??? ?addedge(i+1,i,-1);
?? ??? ?}
?? ??? ?SPFA(s,e);
?? ??? ?printf("%d\n",d[e]);
?? ?return 0;
}
轉載于:https://www.cnblogs.com/Mr-Xu-JH/p/3877262.html
總結
- 上一篇: iOS开发之通知中心(NSNotific
- 下一篇: 分形之万花筒