PAT 1003. Universal Travel Sites (35)

来源:互联网 发布:淘宝vip等级在那里看 编辑:程序博客网 时间:2024/06/18 02:52

After finishing her tour around the Earth, CYLL is now planning a universal travel sites development project. After a careful investigation, she has a list of capacities of all the satellite transportation stations in hand. To estimate a budget, she must know the minimum capacity that a planet station must have to guarantee that every space vessel can dock and download its passengers on arrival.

Input Specification:

Each input file contains one test case. For each case, the first line contains the names of the source and the destination planets, and a positive integer N (<=500). Then N lines follow, each in the format:

sourcei destinationi capacityi

where sourcei and destinationi are the names of the satellites and the two involved planets, and capacityi > 0 is the maximum number of passengers that can be transported at one pass from sourcei to destinationi. Each name is a string of 3 uppercase characters chosen from {A-Z}, e.g., ZJU.

Note that the satellite transportation stations have no accommodation facilities for the passengers. Therefore none of the passengers can stay. Such a station will not allow arrivals of space vessels that contain more than its own capacity. It is guaranteed that the list contains neither the routes to the source planet nor that from the destination planet.

Output Specification:

For each test case, just print in one line the minimum capacity that a planet station must have to guarantee that every space vessel can dock and download its passengers on arrival.
Sample Input:

EAR MAR 11
EAR AAA 300
EAR BBB 400
AAA BBB 100
AAA CCC 400
AAA MAR 300
BBB DDD 400
AAA DDD 400
DDD AAA 100
CCC MAR 400
DDD CCC 200
DDD MAR 300

Sample Output:

700

整个题目的意思可以理解为单源点,单汇点最大流的问题。以下采用的是push-relabel的方法。

#include<iostream>#include<map>#include<string>using namespace std;const int MAX = 1010;int M[MAX][MAX]; // M[i][j] 代表i到j有路经且权值为M[i][j]//map的使用是为了将题中给的字符窜名字与数字序号相对应map<string, int> Map;int map_num = 0;string source, destination;void map_insert(string s, string s1){  map<string, int>::iterator it;  it = Map.find(s);  if(it == Map.end())    Map[s] = map_num++;  it = Map.find(s1);  if(it == Map.end()){    Map[s1] = map_num++;  }}/*void print(){  for(int i = 0; i < 6; i++){    for(int j = 0; j < 6; j++){      cout << M[i][j] << " ";    }    cout << endl;  }}*/int degree[MAX]; //记录各个节点的高度int node_flow[MAX]; //记录各个节点当前所有的流量值//初始化degree数组和node_flow数组void init(int n, int s){  for(int i = 0; i < n; i++){    degree[i] = 0;    node_flow[i] = 0;  }  degree[s] = n;}// 初始源节点尽可能多的向相邻节点输出流量,更新图与各个节点所有的流量void init_source_flow(int s, int n){  for(int i = 0; i < n; i++){    node_flow[s] += M[s][i];    node_flow[i] = M[s][i];    M[i][s] = M[s][i];    M[s][i] = 0;  }  //因为源点为输出流量所以为负数  node_flow[s] = -node_flow[s];}// 检查是否还有非源,汇节点中,节点所有流量值不为零. 有返回不为零的节点;无返回-1;int check_nodes(int s, int t){  for(int i = 0; i < map_num; i++){    if(node_flow[i] && i != s && i != t)      return i;  }  return -1;}void relable_node(int node){  int min_degree = 9999;  for(int i = 0; i < map_num; i++){    if(M[node][i] && degree[i] < min_degree){      min_degree = degree[i];    }  }  degree[node] = min_degree + 1;}void push(int node){  for(int i = 0; i < map_num; i++){    if(node_flow[node] && M[node][i] && degree[node] > degree[i]){      if(node_flow[node] <= M[node][i]){        M[i][node] += node_flow[node];        M[node][i] -= node_flow[node];        node_flow[i] += node_flow[node];        node_flow[node] = 0;        return;      }else{        int tem = M[node][i];        M[i][node] += tem;        M[node][i] = 0;        node_flow[node] -= tem;        node_flow[i] += tem;      }    }  }}int push_relabel(int s, int t){  init(map_num, s);  init_source_flow(s, map_num);  int node = check_nodes(s, t);  while(node != -1){    relable_node(node);    push(node);    node = check_nodes(s, t);  }  return node_flow[t];}/*void print_flow(){  cout << "final node flow:" << endl;  for(int i = 0; i < map_num; i++){    cout << node_flow[i] << " ";  }  cout << "source: " << Map[source] << "  destination: " << Map[destination] << endl;}*/int main(){  string s1, s2;  int N, c;  cin >> source >> destination >> N;  map_insert(source, destination);  for(int i = 0; i < N; i++){    cin >> s1 >> s2 >> c;    map_insert(s1, s2);    M[Map[s1]][Map[s2]] = c;  }  int result =  push_relabel(Map[source], Map[destination]);  //print_flow();  cout << result << endl;  return 0;}
原创粉丝点击