UVA_753_A Plug for UNIX

<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;
	int receptacle, device, adapter;//表示插座數,電器數,轉換器種類  
	vector<string>table_receptacle;
	vector<string>table_device;
	vector<pair<string, string>>table_adapter;
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()
	{
		source = 0;//源點設置成0  
		//接受插座  
		cin >> receptacle; table_receptacle.resize(1);
		for (int i = 0; i < receptacle; i++)
		{
			string type; cin >> type;//插座的類型  
			table_receptacle.push_back(type);
		}
		//接受電器  
		cin >> device; table_device.resize(1);
		for (int i = 0; i < device; i++)
		{
			string name, type; cin >> name >> type;
			table_device.push_back(type);
		}
		//接受適配器  
		cin >> adapter; table_adapter.resize(1);
		for (int i = 0; i < adapter; i++)
		{
			string type1, type2; cin >> type1 >> type2;
			table_adapter.push_back({ type1,type2 });
		}
		//初始化源點,匯點,鄰接表,頂點數  
		source = 0, destination = device + receptacle + adapter + 1, vexnum = 1 + destination;
		flow.resize(vexnum, (vector<int>)vexnum), capacity.resize(vexnum, (vector<int>)vexnum);
		//連邊  
		for (int i = 1; i <= device; i++)
		{
			addEdge(source, i, 1);
			for (int j = 1; j <= receptacle; j++)
			{
				if (table_device[i] == table_receptacle[j])
				{
					addEdge(i, device + j, 1);
				}
			}
			for (int j = 1; j <= adapter; j++)
			{
				if (table_device[i] == table_adapter[j].first)
				{
					addEdge(i, device + receptacle + j, infinity);
				}
			}
		}
		for (int i = 1; i <= receptacle; i++)
		{
			addEdge(device + i, destination, 1);
			for (int j = 1; j <= adapter; j++)
			{
				if (table_receptacle[i] == table_adapter[j].second)
				{
					addEdge(device + receptacle + j, device + i, 1);
				}
			}
		}
		for (int i = 1; i <= adapter; i++)
		{
			for (int j = 1; j <= adapter; j++)
			{
				if (i == j)
				{
					continue;
				}
				if (table_adapter[i].first == table_adapter[j].second)
				{
					addEdge(device + receptacle + j, device + receptacle + i, infinity);
				}
			}
		}
	}
	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]) 
			{   //如果還能增廣,那麼回溯,從匯點往回更新每條走過的邊的流量
				flow[path[from]][from] += remnant[destination];  //更新正向流量   (注意這裏更新的是流量,而不是容量)
				flow[from][path[from]] -= remnant[destination];  //更新反向流量
			}
			maxflow += remnant[destination];
		}
	}
	void print()
	{
		cout << device - maxflow << endl ;
	}
};
int main()
{
	//freopen("input.txt", "r", stdin);  
	//freopen("output.txt", "w", stdout);  
	int n; cin >> n;
	while (n--)
	{
		Network network;
		network.getMaxFlow_EK();
		network.print();
		if (n)
		{
			cout << endl;
		}
	}
	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>
#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 = 2000;
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;
	int receptacle, device, adapter;//表示插座數,電器數,轉換器種類    
	vector<string>table_receptacle;
	vector<string>table_device;
	vector<pair<string, string>>table_adapter;
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);
		source = 0;//源點設置成0    
	    //接受插座    
		cin >> receptacle; table_receptacle.resize(1);
		for (int i = 0; i < receptacle; i++)
		{
			string type; cin >> type;//插座的類型    
			table_receptacle.push_back(type);
		}
		//接受電器    
		cin >> device; table_device.resize(1);
		for (int i = 0; i < device; i++)
		{
			string name, type; cin >> name >> type;
			table_device.push_back(type);
		}
		//接受適配器    
		cin >> adapter; table_adapter.resize(1);
		for (int i = 0; i < adapter; i++)
		{
			string type1, type2; cin >> type1 >> type2;
			table_adapter.push_back({ type1,type2 });
		}
		//初始化源點,匯點,鄰接表,頂點數    
		source = 0, destination = device + receptacle + adapter + 1, vexnum = 1 + destination;
		//連邊    
		for (int i = 1; i <= device; i++)
		{
			addEdge(source, i, 1);
			for (int j = 1; j <= receptacle; j++)
			{
				if (table_device[i] == table_receptacle[j])
				{
					addEdge(i, device + j, 1);
				}
			}
			for (int j = 1; j <= adapter; j++)
			{
				if (table_device[i] == table_adapter[j].first)
				{
					addEdge(i, device + receptacle + j, INF);
				}
			}
		}
		for (int i = 1; i <= receptacle; i++)
		{
			addEdge(device + i, destination, 1);
			for (int j = 1; j <= adapter; j++)
			{
				if (table_receptacle[i] == table_adapter[j].second)
				{
					addEdge(device + receptacle + j, device + i, 1);
				}
			}
		}
		for (int i = 1; i <= adapter; i++)
		{
			for (int j = 1; j <= adapter; j++)
			{
				if (i == j)
				{
					continue;
				}
				if (table_adapter[i].first == table_adapter[j].second)
				{
					addEdge(device + receptacle + j, device + receptacle + i, INF);
				}
			}
		}
	}
	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()
	{
		cout << device-maxflow << endl;
	}
};
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int T; cin >> T;
	while (T--)
	{
		Network network;
		network.getMaxFlow();
		network.print();
		if (T)
		{
			cout << endl;
		}
	}
	return 0;
}







發佈了107 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章