查分约束例题(洛古)

Posted AC_King

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了查分约束例题(洛古)相关的知识,希望对你有一定的参考价值。

昨天看了看差分约束系统的算法。。。做了4道题。。。

P1250 种树

技术分享
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
struct edge{
    int to,w;
};
using namespace std;
const int maxm=100010,maxn=30010,inf=99999999;
int s[maxm],t[maxm],w[maxm],cnt=0,n,dis[maxn];
vector<edge>map[maxn];
void add_edge(int a,int b,int c){
    map[a].push_back((edge){b,c});
}
bool book[maxn];
void spfa(int st){
    queue<int>q;
    q.push(st);
    for(int i=0;i<=n;++i)dis[i]=-inf;
    dis[st]=0;
    book[st]=1;
    while(!q.empty()){
        int t=q.front();
        q.pop();
        book[t]=0;
        for(int i=0;i<map[t].size();++i){
            if(dis[t]!=-inf&&dis[map[t][i].to]<dis[t]+map[t][i].w){
                dis[map[t][i].to]=dis[t]+map[t][i].w;
                if(!book[map[t][i].to]){
                    book[map[t][i].to]=1;
                    q.push(map[t][i].to);
                }
            }
        }
    }
}
int main(){
    int m;
    cin>>n>>m;
    for(int i=0;i<n;++i){
        add_edge(i,i+1,0);
        add_edge(i+1,i,-1);
    }
    for(int i=1;i<=m;++i){
        int a,b,c;
        cin>>a>>b>>c;
        add_edge(a-1,b,c);
    }
    
    for(int i=0;i<=n;++i)add_edge(n+1,i,0);
    spfa(n+1);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=cnt;++j){
            if(dis[s[j]]!=-inf&&dis[s[j]]+w[j]>dis[t[j]]){
                dis[t[j]]=dis[s[j]]+w[j];
            }
        }
    }
    cout<<dis[n];
    return 0;
}
View Code

P1993 小 K 的农场

技术分享
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn=10010,inf=99999999;
struct edge{
    int to,w;
};
int n,dis[maxn];
vector<edge>map[maxn];
void add_edge(int a,int b,int c){
    map[a].push_back((edge){b,c});
}
bool book[maxn];
bool spfa(int st){
    for(int i=1;i<=n;++i)dis[i]=inf;
    book[st]=1;
    queue<int>q;
    q.push(st);
    int cnt=0;
    while(!q.empty()){
        int t=q.front();
        book[t]=0;
        q.pop();
        for(int i=0;i<map[t].size();++i){
            if(dis[t]!=inf&&dis[map[t][i].to]>dis[t]+map[t][i].w){    
                if(book[map[t][i].to]){
                    return 0;
                }
                dis[map[t][i].to]=dis[t]+map[t][i].w;
                book[map[t][i].to]=1;
                q.push(map[t][i].to);
            }
        }
    }
    return 1;
}
int main(){
    int m;
    cin>>n>>m;
    for(int i=1;i<=m;++i){
        int k,s,t,w;
        cin>>k>>s>>t;
        if(k==1){
            cin>>w;
            add_edge(s,t,w);
        }
        else if(k==2){
            cin>>w;
            add_edge(t,s,-w);
        }
        else{
            add_edge(s,t,0);
            add_edge(t,s,0);
        }
    }
    for(int i=1;i<=n;++i)add_edge(n+1,i,0);
    if(spfa(n+1))cout<<"Yes";
    else cout<<"No";
    return 0;
}
View Code

P2294 [HNOI2005]狡猾的商人

技术分享
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxm=5010,inf=99999999;
int s[maxm],t[maxm],w[maxm],dis[110],cnt=0;
void add_edge(int a,int b,int c){
    s[++cnt]=a;
    t[cnt]=b;
    w[cnt]=c;
}
int main(){
    int T;
    cin>>T;
    while(T--){
        int n,m;
        cin>>n>>m;
        cnt=0;
        memset(dis,0,sizeof(dis));
        for(int i=1;i<=m;++i){
            int s,t,w;
            cin>>s>>t>>w;
            add_edge(s-1,t,w);
            add_edge(t,s-1,-w);
        }
        bool flag=0;
        for(int i=0;i<=n;++i)add_edge(n+1,i,0);
        dis[n+1]=0;
        for(int i=1;i<=n+1;++i){
            for(int j=1;j<=cnt;++j){
                if(dis[s[j]]!=inf&&dis[t[j]]>dis[s[j]]+w[j]){
                    dis[t[j]]=dis[s[j]]+w[j];    
                    if(i>=n+1)flag=1;
                }
            }
        }
        if(flag)cout<<"false";
        else cout<<"true";
        cout<<endl;
    }
    return 0;
    
}
View Code

P3275 [SCOI2011]糖果

技术分享
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
struct node {
    int v,w,next;
} d[N*2];
int tot,front[N],n,k;
long long ans;
int dis[N],vis[N],use[N];
queue <int> q;
void add(int u,int v,int w) {
    d[++tot].v = v;
    d[tot].w = w;
    d[tot].next = front[u];
    front[u] = tot;
}
bool spfa() {
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        vis[u] = 0;
        use[u] = 0;
        for(int i=front[u]; i; i=d[i].next) {
            int v = d[i].v,    w = d[i].w;
            if(dis[v] < dis[u] + w) {
                dis[v] = dis[u] +w;
                use[i]++;
                if(use[i]>n-1) return false;
                if(!vis[v]) {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
    return true;
}
int main() {
    scanf("%d %d",&n,&k);
    for(int i=1; i<=k; i++) {
        int op,u,v;
        scanf("%d %d %d",&op,&u,&v);
        if(op==1) {
            add(u,v,0);
            add(v,u,0);
        }
        if(op==2)    add(u,v,1);
        if(op==3)    add(v,u,0);
        if(op==4)    add(v,u,1);
        if(op==5)    add(u,v,0);
        if(op%2==0 && u==v)    {
            printf("-1\n");
            return 0;
        }
    }
    for(int i=1; i<=n; i++) {
        vis[i] = 1;
        dis[i] = 1;
        use[i] = 1;
        q.push(i);
    }
    if(!spfa()) {
        printf("-1\n");
        return 0;
    }
    for(int i=1; i<=n; i++)
        ans+=dis[i];
    printf("%lld\n",ans);
    return 0;
}
View Code

 

以上是关于查分约束例题(洛古)的主要内容,如果未能解决你的问题,请参考以下文章

POJ1201 Intervals查分约束系统(最短路)

HDU 3592 查分约束+判环

洛谷P1993 小 K 的农场(查分约束)

BZOJ2330 糖果题解 查分约束

NOIP模拟赛收银员(一道好的查分约束题)

Cadence 查分对设置