zoukankan      html  css  js  c++  java
  • [网络流24题-11]太空飞行问题

    太空飞行计划问题

    貌似叫最大权闭合子图?(反正这些高端大气上档次的名词我都不知道

    建模比较有趣

    先想最大流 大概是源连实验 实验连仪器 仪器连汇 然后发现无论怎么分配都做不到捆绑并只计算一次费用 弃疗

    最小费用最大流 怎么建都是所有点都选才是最大流 更不靠谱 弃疗

    最小割(不要问我为什么没想上下界 因为我还没学会

    我们发现按照上述最大流的建图方法 然后实验和仪器之间流量为inf 这样的话就可以保证一个实验和他需要的仪器捆绑

    实验和源点之间是贡献 仪器和汇点之间是费用 这样的话就构成了这个模型

    贡献可以这么考虑 本来我们选择的是所有的总贡献 所以割掉一条边其实是减去了贡献 费用更好理解了 割掉了就是花掉了嘛

    所以我们根据最大流=最小割跑一遍最大流

    然后看跟源点相连的实验和仪器就是要选的 所以这个问题就解决啦

    这个题读入真的毒瘤(大雾)

    附代码。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<iostream>
    #define inf 20021225
    #define ll long long
    using namespace std;
    queue<int> que;
    int dis[110],cnt=1,in[110],s,t;
    struct edge{int to,lt,f;}e[60000];
    void add(int x,int y,int f)
    {
    	e[++cnt].to=y;e[cnt].lt=in[x];e[cnt].f=f;in[x]=cnt;
    	e[++cnt].to=x;e[cnt].lt=in[y];e[cnt].f=0;in[y]=cnt;
    }
    bool bfs(int f)
    {
    	while(!que.empty())	que.pop();
    	memset(dis,0,sizeof(dis));
    	que.push(s);dis[s]=1;
    	while(!que.empty())
    	{
    		int x=que.front();que.pop();//printf("%d",x);
    		for(int i=in[x];i;i=e[i].lt)
    		{
    			int y=e[i].to;
    			//printf("%d %d
    ",y,e[i].f);
    			if(!dis[y]&&e[i].f)
    			{
    				dis[y]=dis[x]+1;//printf("%d
    ",y);
    				if(y==t&&f)	return 1;
    				que.push(y);
    			}
    		}
    	}
    	return 0;
    }
    int dfs(int x,int flow)
    {
    	if(x==t||!flow)	return flow;
    	int cur=flow;
    	for(int i=in[x];i;i=e[i].lt)
    	{
    		int y=e[i].to;
    		if(dis[y]==dis[x]+1&&e[i].f)
    		{
    			int tmp=dfs(y,min(cur,e[i].f));
    			e[i].f-=tmp;e[i^1].f+=tmp;cur-=tmp;
    			if(!cur)	return flow;	
    		}
    	}
    	dis[x]=-1;
    	return flow-cur;
    }
    bool vis[110];
    int dinic()
    {
    	int ans=0;
    	while(bfs(1))	ans+=dfs(s,inf);
    	bfs(0);return ans;
    }
    char tools[10000];
    int c[110],ee[110];
    vector<int> v[110];
    int main()
    {
    	int n,m,i,tot=0;
    	scanf("%d%d",&m,&n);
    	s=m+n+1;t=s+1;
    	for(i=1;i<=m;i++)
    	{
    		scanf("%d",&c[i]);
    		add(s,i,c[i]);
    		memset(tools,0,sizeof tools);
    		cin.getline(tools,10000);
    		int ulen=0,tool;
    		while (sscanf(tools+ulen,"%d",&tool)==1)
    		{
    			add(i,tool+m,inf);v[i].push_back(tool);
    			//printf("%d
    ",tool);
    		    if (tool==0) 
    		        ulen++;
    		    else {
    		        while (tool) {
    		            tool/=10;
    		            ulen++;
    		        }
    		    }
    		    ulen++;
    		}
    	}
    	for(i=1;i<=n;i++)	scanf("%d",&ee[i]),add(i+m,t,ee[i]);
    	dinic();
    	for(i=1;i<=m;i++)
    		if(dis[i])
    			printf("%d ",i),tot+=c[i];
    	printf("
    ");
    	for(i=1;i<=n;i++)
    		if(dis[i+m])	printf("%d ",i),tot-=ee[i];
    	printf("
    %d
    ",tot);
    	return 0;
    }
  • 相关阅读:
    Go语言从入门到放弃(三) 布尔/数字/格式化输出
    11. GLOBAL_VARIABLES 与 SESSION_VARIABLES
    10. GLOBAL_STATUS 与 SESSION_STATUS
    9. FILES
    8. EVENTS
    7. ENGINES
    6. COLUMN_PRIVILEGES
    5. COLUMNS
    4. COLLATION_CHARACTER_SET_APPLICABILITY
    3. COLLATIONS
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/10321951.html
Copyright © 2011-2022 走看看