zoukankan      html  css  js  c++  java
  • hdoj--5619--Jam's store(最小费用最大流)

    Jam's store

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 134    Accepted Submission(s): 49


    Problem Description
    Jam didn't study well,then he go to repair the computer in a store,there are M staffs and N guests, given each guests have to spend Tij time to repair the computer by the j staffs.

    Now ask the total of time the guest at least to wait.
    The staff wiil do the next work after he has done the current work
     

    Input
    The first line is T(1T100) means T Case

    For each case

    The first line is M and N(1M,N20) means the number of staffs and guests

    Now given a Matrix with NM each number means the i guests to the j staff time (1Tij1000)
     

    Output
    Output one line about the time at least they need to wait
     

    Sample Input
    1 4 3 4 4 1 5 8 2 5 6 4 5 10 5
     

    Sample Output
    7
    Hint
    the first guest choose the third staff the second guest choose the second staff the third gurst choose the third staff the total of time is 4+2+1=7
    一道比较裸的最大流,刚开始想得有点简单,建图的时候应该是需要分层的,m个服务人员n个顾客,完全可能出现所有的顾客都去一个服务人员那边的情况,所以应该分成n层,对顾客顾客排序,一个顾客的编号可以使1--n,他后边可能有k个人,所以后边的人是需要等k*time,这就是边权,然后就是建立超级源点跟超级汇点,跑一边最大流
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define MAXN 5000+10
    #define MAXM 800000+10
    #define INF 0x3f3f3f3f
    int head[MAXN],cnt;
    struct node
    {
    	int u,v,cap,flow,cost,next;
    }edge[MAXM];
    int pre[MAXN],dis[MAXN];
    bool vis[MAXN];
    void init()
    {
    	cnt=0;
    	memset(head,-1,sizeof(head));
    }
    void add(int u,int v,int w,int c)
    {
    	node E={u,v,w,0,c,head[u]};
    	edge[cnt]=E;
    	head[u]=cnt++;
    	node E1={v,u,0,0,-c,head[v]};
    	edge[cnt]=E1;
    	head[v]=cnt++;
    }
    bool BFS(int s,int t)
    {
    	queue<int>q;
    	memset(dis,INF,sizeof(dis));
    	memset(pre,-1,sizeof(pre));
    	memset(vis,false,sizeof(vis));
    	dis[s]=0;vis[s]=true;
    	q.push(s);
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		vis[u]=false;
    		for(int i=head[u];i!=-1;i=edge[i].next)
    		{
    			node E=edge[i];
    			if(dis[E.v]>dis[E.u]+E.cost&&E.cap>E.flow)
    			{
    				dis[E.v]=dis[E.u]+E.cost;
    				pre[E.v]=i;
    				if(!vis[E.v])
    				{
    					vis[E.v]=true;
    					q.push(E.v);
    				}
    			}
    		}
    	}
    	return pre[t]!=-1;
    }
    void MCMF(int s,int t,int &cost,int &flow)
    {
    	cost=flow=0;
    	while(BFS(s,t))
    	{
    		int Min=INF;
    		for(int i=pre[t];i!=-1;i=pre[edge[i^1].v])
    		{
    			node E=edge[i];
    			Min=min(Min,E.cap-E.flow);
    		}
    		for(int i=pre[t];i!=-1;i=pre[edge[i^1].v])
    		{
    			edge[i].flow+=Min;
    			edge[i^1].flow-=Min;
    			cost+=Min*edge[i].cost;
    		}
    		flow+=Min;
    	}
    }
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while(t--)
    	{
    		int n,m;
    		scanf("%d%d",&m,&n);
    		int S=0,T=n+n*m+1;
    		init();
    		for(int i=1;i<=n;i++)
    		{
    			add(S,i,1,0);
    			for(int j=1;j<=m;j++)
    			{
    				int time;
    				scanf("%d",&time);
    				for(int k=1;k<=n;k++)
    				add(i,j*n+k,1,k*time);
    			}
    		}
    		for(int i=1;i<=m;i++)
    		for(int j=1;j<=n;j++)
    		add(i*n+j,T,1,0);
    		int flow,cost;
    		MCMF(S,T,cost,flow);
    		printf("%d
    ",cost);
    	}
    	return 0;
    }


  • 相关阅读:
    使用Result代替ResultSet作为方法返回值
    java项目使用的DBhelper类
    几种更新(Update语句)查询的方法【转】
    SQL sum case when then else【转】
    解决lucene 重复索引的问题
    在jsp中运用ajax实现同一界面不跳转处理事件
    IIS7如何实现访问HTTP跳转到HTTPS访问 转的
    完整备份数据库+差异备份,恢复到另外一台服务器
    windows mobile ,wince 系统,用代码启动cab文件安装
    compact framework windows mobile wm c#代码 创建快捷方式
  • 原文地址:https://www.cnblogs.com/playboy307/p/5273455.html
Copyright © 2011-2022 走看看