It's time to write up a new blog

BZOJ 2330 & Luogu 3275 candy

There are N kindergarten children, 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 the K requirements. 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.
N ≤ 100000, K ≤ 100000

Each integer is limited to three: X, A, B.

  • If X = 1, A represents a child must be assigned candy and candy of B assigned as many children;

  • If X = 2, A represents a children assigned candy must be less than children assigned to the B-th candy;

  • If X = 3, A represents a child must be at least a share of the candy children assigned to the B-th candy;

  • If X = 4, A denotes a candy must be assigned to children than children assigned to the B-th candy;

  • If X = 5, A represents a child must be assigned to more than candy children assigned to the B-th candy;

Built map:

In the case of x = 1, built from A to B an edge length of 0, and a length of the A building by the B side is 0.

In the case of x = 2, built from the B to the A side of a length of 1, B represents at least one more than A candy.

In the case of x = 3, built from the B to the A side of a length of 0, (pointing to a number of smaller and more candy).

In the case of x = 4, built from A to B as a side length of 1, B represents at least one more than the A candy.

In the case of x = 5, built from A to B an edge length of 0, (pointing to a number of smaller and more candy).

Build a super origin 0 (the origin to limit the number super confectionery> = 1), to each point from the origin super even an edge length of 1.

Starting running the longest path from the super == origin, determines whether there is a ring => no solution

Analyzing edge even order: Consider the longest path dis [v]> = dis [u] + w;

Easy to see that each limit can be expressed as the difference in the form of inequality constraints.

This question is then run single source longest road is very confused right √

Draw a map to understand(Li Jie)a bit(Pirates)

Look mediated a map, if the shortest run, dis No. 1 point = 1, it is clear that the answer should be the No. 1 point 2 is legitimate, so we need to run up the road, in order to meet all of the constraints.

For Case 2 and Case 4, if a> <a or a case where there has been a clearly is no solution.

Then spfa sentenced ring, if there is a point to queue n-1 times, there is a ring? Then no solution output.

Finally, the variables recorded answers to open long long remember

#include<bits/stdc++.h>

using namespace std;

inline int read(){
    int ans=0;
    char last=' ',ch=getchar();
    while(ch>'9'||ch<'0') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}
const int mxm=300010;
const int mxn=300010;

int n,k;
int head[mxn],ecnt;
struct node{
    int to,dis,nxt;
}e[mxm<<1];

void add(int from,int to,int dis){
    ++ecnt;
    e[ecnt].to=to;
    e[ecnt].dis=dis;
    e[ecnt].nxt=head[from];
    head[from]=ecnt;
}

queue<int> q;
bool bj,vis[mxn];
long long dis[mxn],cnt[mxn];
void spfa(int s){
    q.push(s);
    vis[s]=1;
    
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=0;
        if(cnt[u]==n-1){
            bj=1;
            return;
        }
        cnt[u]++;
        for(int i=head[u],v,w;i;i=e[i].nxt){
            v=e[i].to;w=e[i].dis;
            if(dis[v]<dis[u]+w){
                dis[v]=dis[u]+w;
                if(!vis[v]) {
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}

long long ans;

int main(){
    int x,a,b;
    n=read();k=read();
    for(int i=1;i<=k;i++){
        x=read();a=read();b=read();
        if(x==1) {
            add(a,b,0);
            add(b,a,0);
        }
        if(x==2) {
            if(a==b) {
                printf("-1");
                return 0;
            }
            add(a,b,1);
        }
        if(x==3)
            add(b,a,0);
        if(x==4) {
            if(a==b) {
                printf("-1");
                return 0;
            }
            add(b,a,1);
        }
        if(x==5)
            add(a,b,0);
    }
    for(int i=n;i>=1;i--) add(0,i,1);
    spfa(0);
    if(bj){
        printf("-1");
        return 0;
    }
    for(int i=1;i<=n;i++) {
        if(dis[i]==0) {
            printf("-1");
            return 0;
        }
        ans+=dis[i];
    }
    printf("%lld",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/zhuier-xquan/p/11402360.html