uva_259_Software Allocation

#include<iostream>  
#include<sstream>  
#include<string>  
#include<vector>  
#include<list>  
#include<set>  
#include<map>
#include<stack>  
#include<queue>  
#include<algorithm>  
#include<numeric>  
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#pragma warning(disable:4996)  
using std::cin;
using std::cout;
using std::endl;
using std::stringstream;
using std::string;
using std::vector;
using std::list;
using std::pair;
using std::set;
using std::multiset;
using std::map;
using std::multimap;
using std::stack;
using std::queue;
using std::priority_queue;
const int MaxVexNum = 5002;
const int INF = 1000000000;
class Edge
{
public:
	int to, capacity, flow;
	Edge(int t, int c, int f)
	{
		to = t,capacity = c,flow = f;
	}
};
vector<pair<int, int>>direction{ {0,-1},{0,1},{1,0},{-1,0} };
class Network
{
private:
	int vexnum, edgenum, source, destination,maxflow;
	vector<vector<Edge>>adjList;
	map<int, char>number_task;//任务的编号和名称    
public:
	void addEdge(int from, int to, int cap)
	{
		adjList[from].push_back({ to, cap, (int)adjList[to].size() });
		adjList[to].push_back({ from, 0, (int)adjList[from].size() - 1 });
	}
	Network()
	{
		adjList.resize(MaxVexNum);
		maxflow = destination = 0; source = 10;
		//连接pc到汇点    
		for (int i = 1; i <= 10; i++)
		{
			addEdge(i, destination, 1);
		}
		//连接任务到pc    
		string str;
		while (getline(cin, str) && !str.empty())
		{
			stringstream stream; stream << str;
			char task; int number; stream >> task >> number;
			//flow.resize(flow.size()+number, (vector<int>)(flow.size() + number)), capacity.resize(capacity.size() + number, (vector<int>)(capacity.size() + number));  
			for (int i = 1; i <= number; i++)
			{
				number_task.insert({ source + i,task });//记录顶点号和任务的一一对应关系    
			}
			char computer;
			while (stream >> computer)
			{
				if (computer == ';')
				{
					break;
				}
				int pc = computer - '0' + 1;
				for (int i = 1; i <= number; i++)
				{
					addEdge(source + i, pc, 1);
				}
			}
			source += number;
		}
		source++;
		//flow.resize(flow.size() + 1, (vector<int>)(flow.size() + 1)), capacity.resize(capacity.size() + 1, (vector<int>)(capacity.size() + 1));  
		//建立源点到任务的联系    
		for (int i = 11; i<source; i++)
		{
			addEdge(source, i, 1);
		}
		vexnum = source + 1;
	}
	int dfs(int src, int sink, int flow, vector<bool>&used)
	{
		if (src == sink)
		{
			return flow;
		}
		used[src] = true;
		for (int i = 0; i<adjList[src].size(); i++)
		{
			Edge &edge = adjList[src][i];
			if (!used[edge.to] && edge.capacity>0)
			{
				int minflow = dfs(edge.to, sink, std::min(flow, edge.capacity), used);
				if (minflow>0)
				{
					edge.capacity -= minflow;
					adjList[edge.to][edge.flow].capacity += minflow;
					return minflow;
				}
			}
		}
		return 0;
	}
	void getMaxFlow()
	{
		maxflow = 0;
		while (1)
		{
			vector<bool>used(MaxVexNum);
			int f = dfs(source, destination, INF, used);
			if (!f)
			{
				return;
			}
			maxflow += f;
		}
	}
	void print()
	{
		if (number_task.size() == maxflow)
		{
			for (int i = 1; i <= 10; i++)
			{
				bool found = false;
				for (int j = 1; j < adjList[i].size(); j++)
				{
					if (adjList[i][j].capacity)
					{
						cout << number_task[adjList[i][j].to];
						found = true;
						break;
					}
				}
				if (!found)
				{
					cout << '_';
				}
			}
			cout << endl;
		}
		else
		{
			cout << '!' << endl;
		}
	}
};
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	char ch;
	while ((ch = cin.get()) != EOF)
	{
		ungetc(ch, stdin);
		Network network;
		network.getMaxFlow();
		network.print();
	}
	return 0;
}
<pre name="code" class="cpp">#include<iostream>
#include<sstream> 
#include<string> 
#include<vector>
#include<list>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#include<numeric>
#include<cmath>
#pragma warning(disable:4996)
using std::cin;
using std::cout;
using std::endl;
using std::stringstream;
using std::string;
using std::vector;
using std::list;
using std::pair;
using std::set;
using std::multiset;
using std::map;
using std::multimap;
using std::stack;
using std::queue;
using std::priority_queue;
const int infinity =1000000000;
class Network
{
private:
	int vexnum, edgenum, maxflow, source, destination;
	vector<vector<int>>flow, capacity;
	map<int, char>number_task;//任务的编号和名称 
	vector<int>index;
public:
	void addEdge()
	{
		int from, to, c;
		cin >> from >> to >> c;
		capacity[from - 1][to - 1] += c;
	}
	void addEdge(const int &from,const int &to,const int &c)
	{
		capacity[from][to] = c;
	}
	Network()
	{
		maxflow = destination = 0; 
		source = 10;
		flow.resize(100, (vector<int>)100), capacity.resize(100, (vector<int>)100);
		index.resize(10);
		//连接pc到汇点 
		for (int i = 1; i <= 10; i++)
		{
			addEdge(i, destination, 1); 
		}
		//连接任务到pc 
		string str;
		while (getline(cin, str) && !str.empty())
		{
			stringstream stream;
			stream << str;
			char task; int number; stream >> task >> number;
			//flow.resize(flow.size()+number, (vector<int>)(flow.size() + number)), capacity.resize(capacity.size() + number, (vector<int>)(capacity.size() + number));
			for (int i = 1; i <= number; i++)
			{
				number_task.insert({ source + i,task });//记录顶点号和任务的一一对应关系 
			}
			char computer;
			while (stream >> computer)
			{
				if (computer == ';')
				{
					break;
				}
				int pc = computer - '0' + 1;
				for (int i = 1; i <= number; i++)
				{
					addEdge(source + i, pc, 1); 
				}
			}
			source += number;
		}
		source++;
		//flow.resize(flow.size() + 1, (vector<int>)(flow.size() + 1)), capacity.resize(capacity.size() + 1, (vector<int>)(capacity.size() + 1));
		//建立源点到任务的联系
		for (int i = 11; i<source; i++)
		{
			addEdge(source, i, 1);
		}
		vexnum = source + 1;
	}
	void getMaxFlow_EK() 
	{
		maxflow = 0;
		queue<int> Q;
		while (!Q.empty())
		{
			Q.pop();
		}
		vector<int>path(vexnum);
		while (true)
		{
			vector<int>remnant(vexnum);//残余流量得变0,一开始所有点都没流入对吧
			remnant[source] = infinity; //源点嘛,剩余流量无限是必须的...
			Q.push(source); //从源点开始进行BFS找增广路
			int from, to;
			while (!Q.empty()){from = Q.front();Q.pop();for (to = 0; to < vexnum; to++)//遍历所有点,找可行边
			{if (!remnant[to] && capacity[from][to]>flow[from][to]){ //该点剩余流量为0 且 容量大于流量,也就是找到了新的结点 
				path[to] = from; //找到新结点,父节点得记录一下吧
				Q.push(to);remnant[to] = std::min(remnant[from], capacity[from][to] - flow[from][to]); //如果u的剩余流量能填满uv就填满,不能的话就把u这点的流量全部流向uv 
			}}}if (remnant[destination] == 0) //如果当前已经是最大流,汇点没有残余流量
			{break;}for (from = destination; from != source; from = path[from]) { //如果还能增广,那么回溯,从汇点往回更新每条走过的边的流量
				if (from >= 1 && from <= 10){index[from - 1] = path[from];}flow[path[from]][from] += remnant[destination]; //更新正向流量 (注意这里更新的是流量,而不是容量)
				flow[from][path[from]] -= remnant[destination]; //更新反向流量
			}maxflow += remnant[destination];}}void print(){if (maxflow != number_task.size()){cout << '!' << endl;}else{for (int i = 0; i < 10; i++){if (index[i]){cout << number_task[index[i]];}else{cout << '_';}}cout << endl;}}};
int main()
{
	//freopen("input.txt", "r", stdin); 
	//freopen("output.txt", "w", stdout); 
	char ch;
	while ((ch = cin.get()) != EOF)
	{
		ungetc(ch, stdin);
		Network network;
		network.getMaxFlow_EK();
		network.print();
	}
	return 0;
}


 


 
 

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值