zoukankan      html  css  js  c++  java
  • hdu 1384 差分约束系统+SPFA

    要熟练应用差分约束还是很困难的。。。

    题目的大意是:在每个区间[ai,bi]上至少选择ci个元素,构成一个集合S,使集合S中的元素最少;

    不妨设f(a)为区间[0,a]上的选择的元素个数;

    那么,由题意有f(b)-f(a-1)>=c,并且0<=(f(a)-f(a-1))<=1;

    从而建图;

    View Code
     1 #include<iostream>
     2 #include<queue>
     3 #include<cstring>
     4 const int N=50004;
     5 const int Max=1000000;
     6 using namespace std;
     7 
     8 int n,cnt,aa,bb;
     9 int visited[N];
    10 int head[N];
    11 int dist[N];
    12 
    13 struct Edge{
    14     int v,w,next;
    15 }edge[N*4];
    16 
    17 void CreateMap(int u,int v,int w){
    18     edge[cnt].v=v;
    19     edge[cnt].w=w;
    20     edge[cnt].next=head[u];
    21     head[u]=cnt++;
    22 }
    23 
    24 void SPFA(){
    25     memset(visited,0,sizeof(visited));
    26     memset(dist,-1*Max,sizeof(dist));
    27     queue<int>Q;
    28     Q.push(aa);
    29     dist[aa]=0,visited[aa]=1;
    30     while(!Q.empty()){
    31         int v=Q.front();
    32         Q.pop();
    33         visited[v]=0;
    34         for(int i=head[v];i!=-1;i=edge[i].next){
    35             if(dist[edge[i].v]<dist[v]+edge[i].w){
    36                 dist[edge[i].v]=dist[v]+edge[i].w;
    37                 if(!visited[edge[i].v]){
    38                     Q.push(edge[i].v);
    39                     visited[edge[i].v]=1;
    40                 }
    41             }
    42         }
    43         //visited[v]=1;加了这个条件就WA了;
    44     }
    45 }
    46 
    47 int main(){
    48     while(scanf("%d",&n)!=EOF){
    49         memset(head,-1,sizeof(head));
    50         int u,v,w;
    51          aa=Max,bb=0,cnt=0;
    52         for(int i=1;i<=n;i++){
    53             scanf("%d%d%d",&u,&v,&w);
    54             if(u<aa)aa=u;
    55             if(v>bb-1)bb=v+1;
    56             CreateMap(u,v+1,w);
    57         }
    58         for(int i=aa;i<=bb;i++){
    59             CreateMap(i,i-1,-1);   //题目中的隐含条件: 0<=f(a)-f(a-1)<=1;转化为f(a-1)>=f(a)+(-1)&&f(a)>=f(a-1)+0;
    60             CreateMap(i-1,i,0);
    61         }
    62         SPFA();
    63         printf("%d\n",dist[bb]);
    64     }
    65     return 0;
    66 }

    由于求的是最小值,因此要求最长路。。。。即要满足(dist[v]>dist[u]+edge[u][v])。。。

    如果求的是最大值,那么就要求最短路,即要满足(dist[v]<dist[u]+edge[u][v]);

  • 相关阅读:
    I/O多路复用技术
    网络编程的异常及处理
    LINUX的signal
    网络编程小知识
    一个位压缩技巧
    加密技术[翻译]
    暴雪的hash算法[翻译]
    喜欢就好
    【PYTHON】编码是个细致活
    【Python3】POP3协议收邮件
  • 原文地址:https://www.cnblogs.com/wally/p/2890017.html
Copyright © 2011-2022 走看看