zoukankan      html  css  js  c++  java
  • [SCOI2011]糖果

    题目传送门

    对于一个刚接触差分约束系统的OIer来说,这算是一道细节比较多,也比较难的题。首先就是这道题有5种不同的约束条件,对于条件1,3,5直接按照差分条件建边即可,条件2,4要先移项,再建边。之后再求单源最长路,好不容易做出来后你就会发现数据卡SPFA!!!!这里可以加两个小小的优化:1)当a,b严格大于或小于时,他们不能为同一个人,先预判出来可以节省大量时间(不加#5会TLE)。还有要倒序建边,,,(没有任何道理,倒序就能AC,正序会TLE)

    参考程序如下:

      1 #include<iostream>
      2 #include<cstring>
      3 #include<queue>
      4 #include<cstdio>
      5 using namespace std;
      6 long long n,m,dist[350005],v[350005],w[350005],nxt[350005],head[350005],cnt,x,a,b,ring[350005];
      7 bool vis[350005];
      8 inline int read()
      9 {
     10     int f=1,x=0;
     11     char s=getchar();
     12     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
     13     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
     14     return x*f;
     15 }
     16 inline void add(int a,int b,int c)
     17 {
     18     v[++cnt]=b;
     19     w[cnt]=c;
     20     nxt[cnt]=head[a];
     21     head[a]=cnt;
     22 }
     23 inline bool spfa(int node)
     24 {
     25     queue<int>q;
     26     q.push(node);
     27     vis[node]=1;
     28     while(!q.empty())
     29     {
     30         int c=q.front();
     31         q.pop();
     32         vis[c]=0;
     33         ring[c]++;
     34         //cout<<c<<endl;
     35         if(ring[c]==n)return 0;
     36         for(int i=head[c];i;i=nxt[i])
     37         {
     38             int y=v[i];
     39             //cout<<"-------------------CJXGBH---------------------"<<endl;
     40             //cout<<dist[y]<<" "<<dist[c]<<" "<<w[i]<<endl;
     41             if(dist[y]<dist[c]+w[i])
     42             {
     43                 dist[y]=dist[c]+w[i];
     44                 if(!vis[y])
     45                 {
     46                     q.push(y);
     47                     vis[y]=1;
     48                 }
     49             }
     50         }
     51     }
     52     return 1;
     53 }
     54 int main()
     55 {
     56     //freopen("1.in","r",stdin);
     57     n=read();m=read();
     58     for(int i=1;i<=m;i++)
     59     {
     60         x=read();a=read();b=read();
     61         if(x==1)
     62         {
     63             add(a,b,0);
     64             add(b,a,0);    
     65         }
     66         if(x==2)
     67         {
     68             add(a,b,1);
     69             if(a==b)
     70             {
     71                 cout<<"-1";
     72                 return 0;
     73             }
     74         }    
     75         if(x==3)
     76         {
     77             add(b,a,0);
     78         }
     79         if(x==4)
     80         {
     81             add(b,a,1); 
     82             if(a==b)
     83             {
     84                 cout<<"-1";
     85                 return 0;
     86             }       
     87         }
     88         if(x==5)
     89         {
     90             add(a,b,0);
     91         }
     92     }
     93     for(int i=n;i>=1;i--)
     94     {
     95         add(0,i,1);
     96     }
     97     if(!spfa(0))
     98     {
     99         cout<<"-1";
    100         return 0;    
    101     }
    102     long long ans=0;
    103     for(int i=1;i<=n;i++)ans+=dist[i];
    104     cout<<ans; 
    105     return 0;
    106 }
    View Code
  • 相关阅读:
    AxWindowsMediaPlayer的详细用法
    C# Windows Media Player控件的常用属性及方法
    C#中winform使用相对路径读取文件的方法
    DataGridView控件在加载数据时产生的闪烁问题
    浅谈C#中的双缓冲
    几种C#实现播放声音的方法
    C#下实现软件欢迎界面
    DataGridView控件内建立日期选择编辑列
    程序员值得看的电影(20170420EDIT)
    员工照片
  • 原文地址:https://www.cnblogs.com/szmssf/p/11079874.html
Copyright © 2011-2022 走看看