ACM: 最大流 图论题 poj 1797

来源:互联网 发布:麻瓜编程 爬虫 编辑:程序博客网 时间:2024/06/01 21:09
                                                               Heavy Transportation
Description
Background
Hugo Heavy is happy. After the breakdown of the Cargolifter projecthe can now expand business. But he needs a clever man who tells himwhether there really is a way from the place his customer has buildhis giant steel crane to the place where it is needed on which allstreets can carry the weight.
Fortunately he already has a plan of the city with all streets andbridges and all the allowed weights.Unfortunately he has no ideahow to find the the maximum weight capacity in order to tell hiscustomer how heavy the crane may become. But you surely know.

Problem
You are given the plan of the city, described by the streets (withweight limits) between the crossings, which are numbered from 1 ton. Your task is to find the maximum weight that can be transportedfrom crossing 1 (Hugo's place) to crossing n (the customer'splace). You may assume that there is at least one path. All streetscan be travelled in both directions.

Input

The first line contains thenumber of scenarios (city plans). For each city the number n ofstreet crossings (1 <= n <= 1000) andnumber m of streets are given on the first line. The following mlines contain triples of integers specifying start and end crossingof the street and the maximum allowed weight, which is positive andnot larger than 1000000. There will be at most one street betweeneach pair of crossings.

Output

The output for every scenariobegins with a line containing "Scenario #i:", where i is the numberof the scenario starting at 1. Then print a single line containingthe maximum allowed weight that Hugo can transport to the customer.Terminate the output for the scenario with a blank line.

Sample Input

 1
 3 3
 1 2 3
 1 3 4
 2 3 5

Sample Output

Scenario #1:
4

题意: FJ要从1点运送东西到n点. 要求出最大的运送货物总量. (最大流)
      但是每条路的重量的有限制的.即: 最小中找最大的.

解题思路:
         1. 最大流问题. flow记录源点到当前节点的最大流.
         2. 假设u -> v 的当前流量是cur.
          松弛操作是:  int t = min(flow[u],cur);
                      if(flow[v] < t) flow[v] = t;


代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#define MAX 200005
using namespace std;
const int INF = (1<<30);

struct node
{
    int u,v;
    int w;
    intnext;
}edges[MAX];

int n, m;
int num;
int first[MAX];
int flow[MAX];
bool vis[MAX];

inline int min(int a,int b)
{
    return a> b ? b : a;
}

void read_graph()
{
    num =0;
   memset(edges,0,sizeof(edges));
   memset(first,-1,sizeof(first));

    int u, v,w;    
    for(int i =0; i < m; ++i)
    {
      scanf("%d %d%d",&u,&v,&w);
      edges[num].u = u;
      edges[num].v = v;
      edges[num].w = w;
      edges[num].next = first[u];
      first[u] = num++;
      
      edges[num].u = v;
      edges[num].v = u;
      edges[num].w = w;
      edges[num].next = first[v];
      first[v] = num++;
    }
}

int spfa()
{
   memset(vis,false,sizeof(vis));
   memset(flow,0,sizeof(flow));
    
   queue<int>qu;
   qu.push(1);
    vis[1] =true;
    flow[1] =INF;
    
    while(!qu.empty() )
    {
      int u = qu.front();
      qu.pop();
      vis[u] = false;
    
      for(int v = first[u]; v != -1; v =edges[v].next)
      {
         int k =min(flow[u],edges[v].w);  //要通过的流量与当前的限制流量比较
         if(flow[edges[v].v] <k)  //流量松弛操作
         {
            flow[edges[v].v] = k;
            if( !vis[edges[v].v] )
            {
               vis[edges[v].v] = true;
               qu.push(edges[v].v);
            }
         }
      }
    }
    
    returnflow[n];
}

int main()
{
//   freopen("input.txt","r",stdin);
    int t =1;
    intcasesize;
   scanf("%d",&casesize);
    
    while(casesize-- )
    {
      scanf("%d%d",&n,&m);
      printf("Scenario #%d:\n",t++);
      read_graph();
      printf("%d\n\n",spfa());
      
      
    }
    return0;
}
0 0
原创粉丝点击