題意:給了n個區間,要求每個區間至少有C個數字出現,問滿足的最小的數字個數
思路:用Si代表0到i的區間內的數字個數,然後可以寫出查分約束方程,對於一個區間則Sa-S(b-1)>=C的,然後隱含的一個條件就是Si-S(i-1)>=0且<=1的,然後泡個最長路就行,對於查分約束系統求最大值是<=的形式,而求最小值則是>=的形式
#include#include #include #include #include #include using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3fll; const int maxn=50010; int dis[maxn],head[maxn],n,k; bool vis[maxn]; struct edge{ int to,w,next; }E[maxn*10]; void add_edge(int u,int v,int w){ E[k].to=v;E[k].w=w;E[k].next=head[u];head[u]=k++; } void spfa(int S){ queue que; memset(dis,-inf,sizeof(dis)); memset(vis,0,sizeof(vis)); que.push(S);dis[S]=0; while(!que.empty()){ int t=que.front();que.pop(); vis[t]=0; for(int i=head[t];i!=-1;i=E[i].next){ if(dis[t]+E[i].w>dis[E[i].to]){ dis[E[i].to]=dis[t]+E[i].w; if(!vis[E[i].to]){ vis[E[i].to]=1; que.push(E[i].to); } } } } } int main(){ int u,v,c; while(scanf("%d",&n)!=-1){ k=0; memset(head,-1,sizeof(head)); int S=inf,T=-inf; for(int i=0;i