zoukankan      html  css  js  c++  java
  • spfa+差分约束系统(D

    题目链接:https://cn.vjudge.net/contest/276233#problem/D

    给出n个闭合的整数区间[ai,bi]和n个整数c1,…,cn。

    编写一个程序:
    从标准输入中读取间隔数,它们的端点和整数c1,…,cn,
    计算具有间隔[ai,bi]的至少ci共同元素的整数集合Z的最小尺寸,对于每个i = 1,2,…,n,

     具体思路:首先,我们假设存在一个数组s,s[i]记录的是第i个点到第0个点的需要取出的点的个数,对于题目中的从(A,B)至少有d个,我们就可以将这个条件变成posB-(posA-1)>=d,也就是(posA-1)-posB<=-d,这一段的边就建立好了,但是对于这个区间内的每一个数,我们的范围是没有限制的,但是如果没有限制会出现下列情况,s[i]>=i,也就是说会出现矛盾,所以对于这个区间内的没一个数都需要限制,也就是对于区间(i,i+1),我们可以引申出如下条件。0=<pos(i+1)-pos(i)<=1,

    也就是 pos[i+1]-pos[i]>=0(pos[i]-pos[i+1]<=0),和 pos[i+1]-pos[i]<=1,也就是把这段区间的每一个小的区间的条件设立好了就可以了。(注意建边的时候注意方向)

    AC代码:

     1 #include<bits/stdc++.h>
     9 using namespace std;
    10 # define ll long long
    11 # define inf 0x3f3f3f3f
    12 const int maxn = 50000+100;
    13 const int maxedge= 1000000+10;
    14 int num,head[maxn];
    15 int dis[maxn],vis[maxn];
    16 int minx=inf;
    17 int maxy=0;
    18 struct node
    19 {
    20     int fr;
    21     int to;
    22     int cost;
    23     int nex;
    24 } edge[maxedge];
    25 struct point
    26 {
    27     int st;
    28     int ed;
    29 } po[maxn];
    30 void init()
    31 {
    32     for(int i=0; i<=50000; i++)
    33     {
    34         head[i]=-1;
    35         vis[i]=0;
    36         dis[i]=inf;
    37     }
    38     num=0;
    39 }
    40 void addedge(int fr,int to,int cost)
    41 {
    42     edge[num].to=to;
    43     edge[num].cost=cost;
    44     edge[num].nex=head[fr];
    45     head[fr]=num++;
    46 }
    47 ll spfa(int st,int ed)
    48 {
    49     dis[st]=0;
    50     vis[st]=1;
    51     queue<int>q;
    52     q.push(st);
    53     while(!q.empty())
    54     {
    55         int tmp=q.front();
    56         q.pop();
    57         vis[tmp]=0;
    58         for(int i=head[tmp]; i!=-1; i=edge[i].nex)
    59         {
    60             int u=edge[i].to;
    61             if(dis[u]>dis[tmp]+edge[i].cost)
    62             {
    63                 dis[u]=dis[tmp]+edge[i].cost;
    64                 if(vis[u])
    65                     continue;
    66                 vis[u]=1;
    67                 q.push(u);
    68             }
    69         }
    70     }
    71     return dis[ed];
    72 }
    73 int main()
    74 {
    75     int n,d;
    76     scanf("%d",&n);
    77     init();
    78     for(int i=1; i<=n; i++)
    79     {
    80         scanf("%d %d %d",&po[i].st,&po[i].ed,&d);
    81         addedge(po[i].st-1+1,po[i].ed+1,-d);//两个左边都+1,是为了防止出现变成-1的情况。
    82         minx=min(minx,po[i].st);
    83         maxy=max(maxy,po[i].ed+1);
    84     }
    85     for(int i=minx; i<=maxy-1; i++)
    86     {
    87         addedge(i,i+1,0);
    88         addedge(i+1,i,1);
    89     }
    90     int ans=spfa(minx,maxy);
    91     printf("%d
    ",-ans);
    92     return 0;
    93 }
    94 

    E:

    n个数的一个序列,m个约数,si, ni, oi, ki, 代表了序列中第si个数到第si+ni个数的和大于或小于ki,gt = 大于,lt = 小于

    问是否存在相悖的约束

    一个由memset引发的惨案,,,本来是用for循环初始化来着,结果这个题用for一直wa(后来发现是越界了--),然后改成memset的化就给过了。但是顺便加深了对建图的理解(理解写在上面了)。

    AC代码:

       #include<bits/stdc++.h>
      9 using namespace std;
     10 # define ll long long
     11 # define inf 0x3f3f3f3f
     12 const int maxn = 50000+100;
     13 const int maxedge= 1000000+10;
     14 int num,head[maxn],out[maxn];
     15 int dis[maxn],vis[maxn];
     16 int n,m;
     17 struct node
     18 {
     19     int fr;
     20     int to;
     21     int cost;
     22     int nex;
     23 } edge[maxedge];
     24 struct point
     25 {
     26     int st;
     27     int ed;
     28 } po[maxn];
     29 void init()
     30 {
     31     for(int i=0; i<maxn; i++)
     32     {
     33         vis[i]=0;
     34         dis[i]=inf;
     35         head[i]=-1;
     36         out[i]=0;
     37     }
     38     num=0;
     39     num=0;
     40 }
     41 void addedge(int fr,int to,int cost)
     42 {
     43     edge[num].to=to;
     44     edge[num].cost=cost;
     45     edge[num].nex=head[fr];
     46     head[fr]=num++;
     47 }
     48 ll spfa(int st)
     49 {
     50     dis[st]=0;
     51     vis[st]=1;
     52     queue<int>q;
     53     q.push(st);
     54     while(!q.empty())
     55     {
     56         int tmp=q.front();
     57         q.pop();
     58         if(++out[tmp]>n+3)
     59             return -1;
     60         vis[tmp]=0;
     61         for(int i=head[tmp]; i!=-1; i=edge[i].nex)
     62         {
     63             int u=edge[i].to;
     64             if(dis[u]>dis[tmp]+edge[i].cost)
     65             {
     66                 dis[u]=dis[tmp]+edge[i].cost;
     67                 if(vis[u])
     68                     continue;
     69                 vis[u]=1;
     70                 q.push(u);
     71             }
     72         }
     73     }
     74     return 1;
     75 }
     76 int main()
     77 {
     78     while(cin>>n)
     79     {
     80         init();
     81         if(n==0)
     82             break;
     83         cin>>m;
     84         int u,v,d;
     85         string str;
     86         for(int i=1; i<=m; i++)
     87         {
     88             cin>>u>>v>>str>>d;
     89             if(str=="gt")
     90             {
     91                 addedge(u,u+v+1,-(d+1));
     92             }
     93             else
     94             {
     95                 addedge(v+u+1,u,d-1);
     96             }
     97         }
     98         for(int i=1; i<=n+1; i++)
     99         {
    100             addedge(102,i,0);//超级源点的建立过程
    101         }
    102         int ans=spfa(102);
    103         if(ans==-1)
    104             cout<<"successful conspiracy"<<endl;
    105         else
    106             cout<<"lamentable kingdom"<<endl;
    107     }
    108     return 0;
    109 }
    110  

    G题:

    给出数轴上的n个闭合int型区间。现在要在数轴上任意取一堆元素,构成一个元素集合V,要求给出的每个区间和元素集合V的交集至少有两个不同的元素,求集合V最小的元素个数。

    超级源点的建立,为了保证整个区间的连通的,我们就需要建立一个超级源点来使得整个图是连通的,但是注意一点,在正常建边的时候,如果是大的指向小的,这个时候我们建立超级源点的时候就也应该遵循这个原则,如果是是小的指向大的,我们建立超级源点的时候反过来就可以了。

    AC代码:

       #include<bits/stdc++.h>
     9 using namespace std;
    10 # define ll long long
    11 # define inf 0x3f3f3f3f
    12 const int maxn = 10000+100;
    13 const int maxnedge=1000000+100;
    14 struct node
    15 {
    16     int nex;
    17     int to;
    18     int cost;
    19 } edge[maxnedge];
    20 int head[maxn],vis[maxn],dis[maxn],num;
    21 void init()
    22 {
    23     memset(head,-1,sizeof(head));
    24     memset(vis,0,sizeof(vis));
    25     memset(dis,inf,sizeof(dis));
    26     num=0;
    27 }
    28 void addedge(int fr,int to,int cost)
    29 {
    30     edge[num].to=to;
    31     edge[num].nex=head[fr];
    32     edge[num].cost=cost;
    33     head[fr]=num++;
    34 }
    35 int spfa(int st,int ed)
    36 {
    37     queue<int>q;
    38     dis[st]=0;
    39     vis[st]=1;
    40     q.push(st);
    41     while(!q.empty())
    42     {
    43         int tmp=q.front();
    44         q.pop();
    45         vis[tmp]=0;
    46         for(int i=head[tmp]; i!=-1; i=edge[i].nex)
    47         {
    48             int u=edge[i].to;
    49             if(dis[u]>dis[tmp]+edge[i].cost)
    50             {
    51                 dis[u]=dis[tmp]+edge[i].cost;
    52                 if(vis[u])
    53                     continue;
    54                 vis[u]=1;
    55                 q.push(u);
    56             }
    57         }
    58     }
    59     return dis[ed];
    60 }
    61 int main()
    62 {
    63     init();
    64     int n;
    65     scanf("%d",&n);
    66     int u,v;
    67     int minx=inf,maxy=0;
    68     for(int i=1; i<=n; i++)
    69     {
    70         scanf("%d %d",&u,&v);
    71         u+=10;
    72         v+=10;
    73         addedge(u-1,v,-2);
    74         addedge(v,u-1,v-u+1);
    75         minx=min(minx,u-1);
    76         maxy=max(maxy,v);
    77     }
    78     int st=maxy+1;
    80     for(int i=minx; i<maxy; i++){
    82         addedge(st,i,0);
    83         addedge(i,i+1,0);
    84         addedge(i+1,i,1);
    85     }
    86     addedge(st,maxy,0);
    88     int ans=spfa(st,maxy);
    89     printf("%d
    ",-ans);
    90     return 0;
    91 }
    92  
  • 相关阅读:
    [OpenGL ES 071]光照原理
    [OpenGL ES 03]3D变换:模型,视图,投影与Viewport
    [日志]当今最流行的网络生僻字,很火
    [日志]关于茶的基础知识
    [健康]快速除牙痛的八个小验方
    [日志]我们生活中的潜规则
    [日志]做事要方,做人要圆
    [日志]家居装修花钱看你怎么省
    [日志]非常宝贵的工作经验
    [日志]你用的着的一些家装尺寸数据
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262768.html
Copyright © 2011-2022 走看看