"SCOI2011" candy

Original link: http://www.cnblogs.com/GREED-VI/p/10205563.html

Konjac is back to write the solution of the problem. . .

Face questions

There kindergarten  N  a child, lxhgww teacher and now want to give these kids allocation candy, candy requires every child to be assigned.
However, there are kids jealous, always put forward some demands, such as Xiao Ming does not want red candy assigned more than his, so when the distribution of candy, lxhgww need to meet the children of  K  requirement.
Kindergarten candy is always limited, lxhgww he at least wanted to know how many candy need to make every child can be assigned candy, and children meet all the requirements.

Input Format

The first line of input two integers  N K  .
Next  K  lines, showing the relationship of these points need to be met for each row  . 3 3 numbers,  X  ,  A  ,  B  .
If the  X-=. 1 . It represents  A  small friend must be assigned candy and  B  th children assigned as many fine fruit.
If the  X-= 2  , represents  A  small friend assigned candy must be less than the first  B  th children assigned candy.
If the  X-=. 3  , represents the  A  th children assigned candy must be not less than  B  th children assigned candy.
If the  X-=. 4  , represents  A  small friend must be assigned to more than candy of  the B children assigned candy.
If the  X-=. 5  , represents  A A children's candy must be assigned to no more than the first  B assigned to a children's candy.

Output Format

Output a line representing the number of candy lxhgww teacher at least need to be prepared, if you can not meet all the requirements of the children, it is output  -1 .

Thinking

Immortal title (not the idea, but when the gods card ...)

But still look at the ideas. . .

Can be obtained by a 1 x == A == B, is equal on both sides, to build a bi-a to b is the right side of zero.

It can be obtained by a 2 x == A <B, so let A + x (x> = 1)> B, b to a weight build a unidirectional 1 side.

Can be obtained by the x == 3 A> = B, so let B + x (x> = 0)> = A, b to a weight build a unidirectional 0 side.

X == available from the A> B 4, the so let B + x (x> = 1)> A, b to a weight build a unidirectional 1 side.

Can be obtained by the x == 5 A <= B, so let A + x (x> = 0)> = B, b to a weight build a unidirectional 0 side.

The inequality is then taken with a large large, the longest run a SPFA passage (way sentence rings) on the line (and not A).

???

In case x == 2 || x == 4 Shi A == B then? You have to rerun it again? ? ? Direct determination Laid cout << - 1 << endl; return 0;

In case burst int it? Open long long bar

just in case. . . I did not expect this. . .

90 minute look at the code

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
struct node{long long dis,to,next;}Edge[1000005];
long long head[1000005],cnt=0,N,K;    
bool vis[1000005];
long long dis[1000005],tot[1000005];
inline long long read() {
    int ret=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
    while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
    return ret*f;
}
void add(long long a,long long b,long long c)
{
    Edge[++cnt].next=head[a];
    Edge[cnt].to=b;
    Edge[cnt].dis=c;
    head[a]=cnt;
}
void SPFA(long long s)
{
    for (long long i=1;i<=N;i++) vis[i]=0,dis[i]=-2e9,tot[i]=0;
    queue<int> q;
    q.push(s); vis[s]=1; dis[s]=0; tot[s]++;
    while(!q.empty())
    {
        long long u=q.front();
        q.pop();
        vis[u]=0;
        for (long long i=head[u];i;i=Edge[i].next)
        {
            long long v=Edge[i].to;
            if (dis[v]<dis[u]+Edge[i].dis)
            {
                dis[v]=dis[u]+Edge[i].dis;
                if (!vis[v]&&tot[v]<N) tot[v]++,q.push(v),vis[v]=0;
                else if (tot[v]>=N) 
                {
                cout<<-1<<endl;
                exit(0);
                return;
                }
            }
            
        }
    }
}
int main ()
{
    N=read();K=read();
    for (long long i=1;i<=K;i++)
    {
        long long X,A,B;
        X=read();A=read();B=read();
        if (X==1) add(A,B,0),add(B,A,0);
        if (X==2) 
        if (A==B) {cout<<-1<<endl;return 0;}
        else add(A,B,1);
        if (X==3) add(B,A,0);
        if (X==4) 
        if (A==B) {cout<<-1<<endl;return 0;}
        else add(B,A,1);
        if (X==5) add(A,B,0);
    }
    long long s=0;
    for (long long i=1;i<=N;i++) add(s,i,1);
    SPFA (s);
    long long ans=0;
    for (long long i=1;i<=N;i++) ans+=dis[i];
    cout<<ans<<endl;
    return 0;
}
View Code

Look again at the code 100

#include<bits/stdc++.h>
using namespace std;
struct node{long long dis,to,next;}Edge[1000005];
long long head[1000005],cnt=0,N,K;    
bool vis[1000005];
long long dis[1000005],tot[1000005];
inline long long read() {
    int ret=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
    while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
    return ret*f;
}
void add(long long a,long long b,long long c)
{
    Edge[++cnt].next=head[a];
    Edge[cnt].to=b;
    Edge[cnt].dis=c;
    head[a]=cnt;
}
void SPFA(long long s)
{
    for (long long i=1;i<=N;i++) vis[i]=0,dis[i]=-1,tot[i]=0;
    queue<long long> q;
    q.push(s); vis[s]=1; dis[s]=0; tot[s]++;
    while(!q.empty())
    {
        long long u=q.front();
        q.pop();
        vis[u]=0;
        for (long long i=head[u];i;i=Edge[i].next)
        {
            long long v=Edge[i].to;
            if (dis[v]<dis[u]+Edge[i].dis)
            {
                dis[v]=dis[u]+Edge[i].dis;
                if (!vis[v]&&tot[v]<N) tot[v]++,q.push(v),vis[v]=0;
                else if (tot[v]>=N) 
                {
                cout<<-1<<endl;
                exit(0);
                return;
                }
            }
            
        }
    }
}
int main ()
{
    N=read();K=read();
    for (long long i=1;i<=K;i++)
    {
        long long X,A,B;
        X=read();A=read();B=read();
        if (X==1) add(A,B,0),add(B,A,0);
        if (X==2)
        { 
        if (A==B) {cout<<-1<<endl;return 0;}
        else add(A,B,1);
        }
        if (X==3) add(B,A,0);
        if (X==4) 
        {
        if (A==B) {cout<<-1<<endl;return 0;}
        else add(B,A,1);
        }
        if (X==5) add(A,B,0);
    }
    Long  Long S = 0 ;
     for ( Long  Long I = N; I> = . 1 ; i--) the Add (S, I, . 1 ); // optimize gods, see is earned
    SPFA (s);
    long long ans=0;
    for (long long i=1;i<=N;i++) ans+=dis[i];
    cout<<ans<<endl;
    return 0;
}

. . . Dalao waiting for answers

 

Reproduced in: https: //www.cnblogs.com/GREED-VI/p/10205563.html

Guess you like

Origin blog.csdn.net/weixin_30546933/article/details/94794322