BZOJ 1520 POI2006 Szk-Schools

1520: [POI2006]Szk-Schools

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 771  Solved: 398
[Submit][Status][Discuss]

Description

Input

Output

如果有可行解, 输出最小代价,否则输出NIE.

Sample Input

5
1 1 2 3
1 1 5 1
3 2 5 5
4 1 5 10
3 3 3 1

Sample Output

9

HINT

 

Source

很裸的费用流

#include <bits/stdc++.h>
#define ll long long
#define inf 1e9+10
using namespace std;
inline int read(){
	int x=0;int f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
	return x*f;
} 
const int MAXN=1e5+10;
struct node{
	int y,next,back,flow,w;
}e[MAXN];
int linkk[MAXN],len=0,vis[405],dis[405],s,t,n,ans=0;
inline void insert(int x,int y,int f,int c){
	e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;e[len].back=len+1;e[len].flow=f;e[len].w=c;
	e[++len].y=x;e[len].next=linkk[y];linkk[y]=len;e[len].back=len-1;e[len].flow=0;e[len].w=-c;
}
inline bool getdis(){
	memset(dis,10,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[t]=0;vis[t]=1;
	deque<int>q;q.push_front(t);
	while(!q.empty()){
		int tn=q.front();q.pop_front();
		for(int i=linkk[tn];i;i=e[i].next){
			if(e[e[i].back].flow&&dis[e[i].y]>dis[tn]-e[i].w){
				dis[e[i].y]=dis[tn]-e[i].w;
				if(!vis[e[i].y]){
					if(!q.empty()&&dis[q.front()]>dis[e[i].y]) q.push_front(e[i].y);
					else q.push_back(e[i].y);vis[e[i].y]=1;
				}
			}
		}
		vis[tn]=0;
	}
	return dis[s]<168430090;
}
inline int getcost(int x,int flow){
	int f=0,d;vis[x]=1;
	if(x==t) return flow;
	for(int i=linkk[x];i;i=e[i].next){
		if(!vis[e[i].y]&&e[i].flow&&dis[e[i].y]==dis[x]-e[i].w){
			if(d=getcost(e[i].y,min(e[i].flow,flow-f))){
				f+=d;e[i].flow-=d;e[e[i].back].flow+=d;
				ans+=e[i].w*d;if(f==flow) return flow;
			}
		}
	}
	return f;
}
inline int zkw(){
	int sum=0;
	while(getdis()){
		vis[t]=1;
		while(vis[t]){
			memset(vis,0,sizeof(vis));
			sum+=getcost(s,inf);
		}
	}
	return sum;
}
int main(){
	n=read();s=0;t=2*n+1;
	for(int i=1;i<=n;i++){
		int m=read();int x=read();int y=read();int k=read();
		for(int j=x;j<=y;j++){
			insert(i,j+n,1,abs(m-j)*k);
		}
		insert(s,i,1,0);
		insert(i+n,t,1,0);
	}
	int sum=zkw();
	if(sum==n) cout<<ans<<endl;
	else cout<<"NIE"<<endl;
	return 0;
}

  

posted @ 2018-05-18 23:01  zhangenming  阅读(154)  评论(0编辑  收藏  举报