真心给zkw大神跪了。。。
这个算是模板题,不过构图显然不是我想出来的。。。。
算是第一个费用流。。。
以后要多写点网络流啊。。
一开始我用vector存的边然后交上去竟然TLE!!!!!
这简直就是对vector党的鄙视啊。。。
然后没办法把vector注释掉换前向星了。。。
看来以后只能用前向星存图了。。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<deque>
//#include<vector>
#define inf 100000007
#define MAX 55555
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define pb push_back
using namespace std;
int n,N,e=0,head[MAX];
void read(int &x)
{
char c;
int ret=0;
while(c=getchar(),(c<'0'||c>'9')&&c!='-');
if(c!='-')
{
ret=c-'0';
while(c=getchar(),c>='0'&&c<='9')
ret*=10,ret+=c-'0';
x=ret;
return;
}
else
{
while(c=getchar(),c>='0'&&c<='9')
ret*=10,ret+=c-'0';
x=-ret;
return;
}
}
struct ZKW
{
struct Edge
{
int cost,cap,to,next,re;
};
//vector<Edge>edge;
//vector<int>aim[MAX];
Edge edge[MAX];
/* void addedge(int From,int To,int Cap,int Cost)
{
edge.pb((Edge){From,To,Cap,Cost});
edge.pb((Edge){To,From,0,-Cost});
int size=edge.size();
aim[From].pb(size-2);
aim[To].pb(size-1);
}*/
void add_edge(int From,int To,int Cap,int Cost)
{
e++;
edge[e].to=To;
edge[e].cap=Cap;
edge[e].cost=Cost;
edge[e].re=e+1;
edge[e].next=head[From];
head[From]=e;
e++;
edge[e].to=From;
edge[e].cap=0;
edge[e].cost=-Cost;
edge[e].re=e-1;
edge[e].next=head[To];
head[To]=e;
}
int s,t,cost,dis[MAX],done[MAX];
int MinCost;
/* void debug()
{
int w;
for(int i=0;i<edge.size();i++)
printf("%d %d\n",edge[i].from,edge[i].to);
}*/
void clear()
{
/*edge.clear();
rep(i,0,n)
aim[i].clear();*/
memset(head,-1,sizeof(head));
e=0;
MinCost=cost=0;
return;
}
bool modlabel()
{
memset(dis,63,sizeof(dis));
dis[t]=0;
deque<int>q;
q.push_back(t);
while(!q.empty())
{
int now=q.front(),tmp;
q.pop_front();
/*for(int i=0;i<aim[now].size();i++)
{
int w=aim[now][i];
if(edge[w^1].cap&&(tmp=dis[now]-edge[w].cost)<dis[edge[w].to])
{
if((dis[edge[w].to]=tmp)<=dis[q.empty()?s:q.front()])
q.push_front(edge[w].to);
else
q.push_back(edge[w].to);
}
}*/
for(int i=head[now];i!=-1;i=edge[i].next)
if(edge[edge[i].re].cap&&(tmp=dis[now]-edge[i].cost)<dis[edge[i].to])
{
if((dis[edge[i].to]=tmp)<=dis[q.empty()?s:q.front()])
q.push_front(edge[i].to);
else
q.push_back(edge[i].to);
}
}
rep(i,s,t)//?
/*for(int j=0;j<aim[i].size();j++)
{
int w=aim[i][j];
edge[w].cost+=dis[edge[w].to]-dis[edge[w].from];
}*/
for(int j=head[i];j!=-1;j=edge[j].next)
edge[j].cost+=dis[edge[j].to]-dis[i];
cost+=dis[s];
return dis[s]<inf;
}
int aug(int x,int f)//?
{
if(x==t)
{
MinCost+=f*cost;
return f;
}
done[x]=1;
int tmp=f;
/*for(int i=0;i<aim[x].size();i++)
{
int now=aim[x][i];
if(edge[now].cap&&!edge[now].cost&&!done[edge[now].to])
{
int delta=aug(edge[now].to,min(tmp,edge[now].cap));
edge[now].cap-=delta;
edge[now^1].cap+=delta;
tmp-=delta;
if(!tmp)
return f;
}
}*/
for(int i=head[x];i!=-1;i=edge[i].next)
if(edge[i].cap&&!edge[i].cost&&!done[edge[i].to])
{
int delta=aug(edge[i].to,min(tmp,edge[i].cap));
edge[i].cap-=delta;
edge[edge[i].re].cap+=delta;
tmp-=delta;
if(!tmp)
return f;
}
return f-tmp;
}
int work(int S,int T)
{
this->s=S;
this->t=T;
MinCost=0;
while(modlabel())
{
do
{
memset(done,0,sizeof(done));
}while(aug(s,inf));
}
return -MinCost;
}
}wbysr;
int k,a[MAX],b[MAX],w[MAX],New[MAX],cnt,S,T;
inline void init()
{
read(N),read(k);
//scanf("%d%d",&N,&k);
cnt=0;
rep(i,1,N)
{
read(a[i]),read(b[i]),read(w[i]);
// scanf("%d%d%d",&a[i],&b[i],&w[i]);
New[++cnt]=a[i];
New[++cnt]=b[i];
}
sort(New+1,New+1+cnt);
cnt=unique(New+1,New+1+cnt)-New-1;
}
int search(int x)
{
int l=1,r=cnt;
while(l<=r)
{
int mid=(l+r)>>1;
if(New[mid]==x)
return mid;
if(New[mid]<x)
l=mid+1;
else
r=mid-1;
}
return -1;
}
inline void build()
{
rep(i,1,N)
wbysr.add_edge(search(a[i]),search(b[i]),1,-w[i]);
n=cnt;
rep(i,1,n-1)
wbysr.add_edge(i,i+1,k,0);
S=0;
T=cnt+1;
wbysr.add_edge(S,1,k,0);
wbysr.add_edge(T-1,T,k,0);
return;
}
int main()
{
int time;
scanf("%d",&time);
while(time--)
{
getchar();
wbysr.clear();
init();
build();
printf("%d\n",wbysr.work(S,T));
}
return 0;
}