poj3680

题解:

相邻的建边

每一段建边

然后见一个原点,汇点

代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=100005;
int b[N],T,c[N],fi[N],n,t,cas,m,x,mp[N],k,a[N];
int y,z,f[N],ne[N],num,zz[N],fl[N],gp[N],dist[N],pre[N],sl[N];
void jb(int x,int y,int z,int s)
{
    ne[num]=fi[x];
    fi[x]=num;
    zz[num]=y;
    sl[num]=z;
    fl[num++]=s;
    ne[num]=fi[y];
    fi[y]=num;
    zz[num]=x;
    sl[num]=0;
    fl[num++]=-s;
}
int spfa()
{
    memset(dist,0x3f,sizeof dist);
    memset(pre,-1,sizeof pre);
    memset(gp,0,sizeof gp);
    memset(f,0,sizeof f);
    queue<int > Q;
    Q.push(1);
    dist[1]=0;
    while (!Q.empty())
     {
         int now=Q.front();
         Q.pop();
         f[now]=0;
         for (int i=fi[now];i!=-1;i=ne[i])
          if (sl[i]>0)
           {
              int t=zz[i];
              if (dist[t]>dist[now]+fl[i])
               {
                   dist[t]=dist[now]+fl[i];
                   pre[t]=now;
                   gp[t]=i;
                   if (!f[t])
                    {
                        f[t]=1;
                        Q.push(t);
                    }
               }
           }
     }
    if (pre[n+2]==-1)return 1;
    return 0; 
}
void Max_flow()
{
    int cost=0,flow=0;
    while (!spfa())
     {
         int f=1e9;
         for (int i=n+2;i>1;i=pre[i])
          f=min(f,sl[gp[i]]);
         cost+=f;
        flow+=dist[n+2]*f;
        for (int i=n+2;i>1;i=pre[i])
         {
             sl[gp[i]]-=f;
             sl[gp[i]^1]+=f;
         } 
     }
    printf("%d
",-flow); 
}
void init()
{
//    printf("Instance #%d: ",++cas);
    num=0;
    memset(mp,0,sizeof mp);
    memset(fi,-1,sizeof fi);
}
void doit()
{
    scanf("%d%d",&n,&k);
    for (int i=1;i<=n;i++)
     {
         scanf("%d%d%d",&a[i],&b[i],&c[i]);
         f[i*2-1]=a[i];f[i*2]=b[i];
     }
    sort(f+1,f+n+n+1);
    mp[f[1]]=1;
    int tot=1;
    for (int i=2;i<=2*n;i++)
     if (f[i]!=f[tot])mp[f[i]]=++tot,f[tot]=f[i];
    for (int i=2;i<=tot;i++)jb(i,i+1,k,0);
    for (int i=1;i<=n;i++)jb(mp[a[i]],mp[b[i]],1,-c[i]);
    jb(1,2,k,0);jb(tot+1,tot+2,k,0);
    n=tot; 
    Max_flow();
}
int main()
{
    scanf("%d",&T);
    while (T--)
     {
         init();
         doit();
     }
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8394742.html