ACM-ICPC 2018 焦作赛区网络预赛 F. Modular Production Line

版权声明:本博客内容基本为原创,如有问题欢迎联系,转载请注明出处 https://blog.csdn.net/qq_41955236/article/details/82755034

题目链接:https://nanti.jisuanke.com/t/31715

题意:

       给你n个部件,每个部件最多用k次,现在有m种组装子部件的方式可以赚得额外的权值,但是每种方法最多只会被用一次。组装子部件需要ai,bi两个部件(两个都会被用一次),可以得到wi的价值。

做法:

       知道是裸题有点小难受,当时根本就没看(当时也不会这个k区间)。这个题的连边有点不一样,是从u连向v+1的,为什么呢。因为两边的点都会被用到,所以覆盖到的其实是u,v的区间。之前的题是v可以马上开始另一件任务,是[ )的关系,这个题是两边都会覆盖到,是[ ] 的关系,所以需要我们要把区间设置成v+1。然后套个板子就A啦啦。

       至于建图,https://blog.csdn.net/qq_41955236/article/details/82744109这里讲的比较详细。

#include <map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn=6000;
const int maxm=20000;
const int inf=0x3f3f3f3f;
int dis[maxn];
int vis[maxn],pre[maxn];
int head[maxn],cnt;
int n,m,sp,tp,k;
struct node{
    int to,cap,next;
    ll cost;
}e[maxm];
map<int,int> mp;
void add(int from,int to,int cap,ll cost){
    e[cnt].to=to; e[cnt].cap=cap;
    e[cnt].cost=cost; e[cnt].next=head[from];
    head[from]=cnt++;

    e[cnt].to=from; e[cnt].cap=0;
    e[cnt].cost=-cost; e[cnt].next=head[to];
    head[to]=cnt++;
}
bool spfa(int s,int t,int &flow,ll &cost){
    queue<int> q;
    memset(dis,inf,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(pre,-1,sizeof(pre));
    dis[s]=0;  q.push(s);
    vis[s]=1;
    int d=inf;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];~i;i=e[i].next){
            int v=e[i].to;
            if(e[i].cap>0&&dis[v]>dis[u]+e[i].cost){
                dis[v]=dis[u]+e[i].cost;
                pre[v]=i;
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    if(dis[t]==inf){
        return false;
    }
    for(int i=pre[t];~i;i=pre[e[i^1].to]){
        d=min(d,e[i].cap);
    }
    for(int i=pre[t];~i;i=pre[e[i^1].to]){
        e[i].cap-=d;
        e[i^1].cap+=d;
        cost+=e[i].cost*d;
    }
    flow+=d;
    return true;
}
ll mcmf(int s,int t){
    int flow=0;
    ll cost=0;
    while(spfa(s,t,flow,cost)){
        //cout<<flow<<" "<<cost<<endl;
    }
    return cost;
}
struct nodes{
    int u,v;
    ll c;
}ee[2500];
int main(){
    int t;
    cin>>t;
    while(t--){
        int tmp[1005],numtmp=0; mp.clear();
        scanf("%d%d%d",&n,&k,&m);
        cnt=0;
        memset(head,-1,sizeof(head));
        sp=0; tp=n+1;
        for(int i=0;i<m;i++){
            scanf("%d%d%lld",&ee[i].u,&ee[i].v,&ee[i].c);
            tmp[numtmp++]=ee[i].u,tmp[numtmp++]=ee[i].v;
        }
        sort(tmp,tmp+numtmp);
        int cc=unique(tmp,tmp+numtmp)-tmp;
        numtmp=0;

        for(int i=0;i<cc;i++){
            mp[tmp[i]]=++numtmp;
        }
        for(int i=0;i<m;i++){
            int u=mp[ee[i].u],v=mp[ee[i].v];
            add(u,v+1,1,-ee[i].c);
        }
        for(int i=1;i<numtmp;i++)
            add(i,i+1,k,0);
        tp=numtmp+1;
        add(sp,1,k,0); add(numtmp,tp,k,0);
        printf("%lld\n",-mcmf(sp,tp));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41955236/article/details/82755034