uva 11248 Frequency Hopping(增加边的容量使最大流达到某个值)

Time Limit: 10000MSMemory Limit: Unknown64bit IO Format: %lld & %llu

[Submit]   [Go Back]   [Status]  

Description

Download as PDF

E

Frequency Hopping

Input: Standard Input

Output: Standard Output

 

 

 

20th July, 1942

Confidential

Colonel Al Pacheno,

      According to the previous order “ref: 232/UK44i/334sda#nh$X3y”, you are required back in the DOI (Department of intelligence, London ) to head the special programming contingent immediately. You are to assign a programmer for the job whose specification is attached with this letter.

      Level 3 Secrecy must be maintained.

 

Sincerely,

General Shaan Konary

Director, DOI

London

 

Ps: Sorry to ruin your Caribbean holiday

 

 

232/UK44i/334sda#nh$X3y/Appx-301a

At this moment, through out Europe , our base station numbers 1 to N are actively operational through wireless channels. Immediately we require sending C secret message fragments from our head quarters (base station 1) to Nth base station. Germans have developed Zämmhäim – a machine which jams the frequency channel between base stations after a station has sent a message fragment. In that case, the base stations must transmit using a different frequency channel for each message fragment. There are several unidirectional channels set up between base stations at this moment. We can only make arrangements to set up number of frequency channels only between two base stations. Your task is to check whether all the message fragments can be sent to the desired base station with or without increasing frequency channel between any two particular base stations. You have to give us all possible options if it is required to increase frequency channel between two stations.

--End of Attachment

 

As members of Secret Programmers Group (SPG) you are assigned to solve this problem within 5 hrs and deliver the solution directly to Colonel Al Pacheno. You have to maintain Level 3 secrecy and destroy all documents corresponding to this as soon as you deliver the solution.

 

Input:

There will be multiple test cases. The first line of each test case contains three numbers N, E and C where N (0<N<101) represents the number of base stations, E (E<10000) represents the number of available connections between the base stations and C (C<2000000000) represents the number of secret message fragments that are required to send from station 1 to station N. After that, there will be E lines. Each line contains 3 numbers: b1(0<b1<101), b2(0<b2<101) and fp(0<fp<5001) which represent the number of frequency channels available currently from b1 to b2. Input is terminated when N=E=C=0.

 

Output:

For each test case, there will be one line of output. First, you have to print the case number. If it is possible to send C secret message fragments from the current status the output will be “possible”. Otherwise, you have to print all pairs of stations (in ascending order) if it is possible send the required message fragments by increasing the frequency channel between any one of them. If it is still impossible, you have to print “not possible”.

 

Sample Input                            Output for Sample Input

4 4 5

1 2 5

1 3 5

2 4 5

3 4 5

4 4 5

1 2 1

1 3 5

2 4 5

3 4 1

4 4 5

1 2 1

1 3 1

2 4 1

3 4 1

0 0 0

 

Case 1: possible

Case 2: possible option:(1,2),(3,4)

Case 3: not possible

 




题意:给出一个有向网络,问是否存在一个从点1到点N,流量为C的流。如果不存在,是否可以恰好修改一条弧的容量,使得存在这样的流?
思路:先求一次最大流,如果流量至少为C,则存在这样的流。否则,需要修改的弧一定是最小割中的弧,所以要枚举最小割中的每条边,使这条边的容量增加到C,然后求最大流,看最大流是否为C。然而这种做法会超时,需要加两个重要优化。第一个优化是求完最大流后把流量留着,以后每次在它的基础上增广。第二个优化是每次没必要求出最大流,增广到流量至少为C时就停下。

 AC代码:
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>
#include <stack>
#include <ctime>
#include <vector>
#include <algorithm>
#define ll long long
#define L(rt) (rt<<1)
#define R(rt)  (rt<<1|1)
using namespace std;

const int INF = 1e9;
const int maxn = 1005;

struct Edge{
    int u, v, cap, flow, next;
}et[maxn * maxn];
int cnt[maxn], low[maxn], dis[maxn], pre[maxn], cur[maxn], eh[maxn];
int col[maxn];
int n, m, C, s, t, num;
typedef pair<int, int> pii;
vector<pii> ans;
vector<int> mincut;
void init(){
    memset(eh, -1, sizeof(eh));
    memset(col, 0, sizeof(col));
    ans.clear();
    mincut.clear();
    num = 0;
}
void add(int u, int v, int cap, int flow){
    Edge e = {u, v, cap, flow, eh[u]};
    et[num] = e;
    eh[u] = num++;
}
void addedge(int u, int v, int cap){
    add(u, v, cap, 0);
    add(v, u, 0, 0);
}
int isap(int s, int t, int nv, int need){
    int u, v, now, flow = 0;
    memset(low, 0, sizeof(low));
    memset(cnt, 0, sizeof(cnt));
    memset(dis, 0, sizeof(dis));
    for(u = 0; u <= nv; u++) cur[u] = eh[u];
    low[s] = INF, cnt[0] = nv, u = s;
    while(dis[s] < nv)
    {
        for(now = cur[u]; now != -1; now = et[now].next)
        if(et[now].cap - et[now].flow && dis[u] == dis[v = et[now].v] + 1) break;
        if(now != -1)
        {
            cur[u] = pre[v] = now;
            low[v] = min(low[u], et[now].cap - et[now].flow);
            u = v;
            if(u == t)
            {
                for(; u != s; u = et[pre[u]].u)
                {
                    et[pre[u]].flow += low[t];
                    et[pre[u]^1].flow -= low[t];
                }
                flow += low[t];
                if(flow >= need) return flow;
                low[s] = INF;
            }
        }
        else
        {
            if(--cnt[dis[u]] == 0) break;
            dis[u] = nv, cur[u] = eh[u];
            for(now = eh[u]; now != -1; now = et[now].next)
            if(et[now].cap - et[now].flow && dis[u] > dis[et[now].v] + 1)
            dis[u] = dis[et[now].v] + 1;
            cnt[dis[u]]++;
            if(u != s) u = et[pre[u]].u;
        }
    }
    return flow;
}
void dfs(int u){
    col[u] = 1;
    for(int i = eh[u]; i != -1; i = et[i].next)
    if(et[i].cap - et[i].flow)
    {
        int v = et[i].v;
        if(!col[v]) dfs(v);
    }
}
void clearflow(){
    for(int i = 0; i < num; i++) et[i].flow = 0;
}
bool cmp(pii a, pii b){
    if(a.first != b.first) return a.first < b.first;
    return a.second < b.second;
}
int main()
{
    int a, b, c, ca = 0;
    while(scanf("%d%d%d", &n, &m, &C), n || m || C)
    {
        init();
        s = 1;
        t = n;
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d%d", &a, &b, &c);
            addedge(a, b, c);
        }
        printf("Case %d: ", ++ca);
        int flow = isap(s, t, t + 1, C);
        if(flow >= C)
        {
            printf("possible\n");
            continue;
        }
        dfs(s);
        for(int i = 0; i < num; i += 2)
        {
            int u = et[i].u, v = et[i].v;
            if(col[u] == 1 && col[v] == 0)
            mincut.push_back(i);
        }
        for(int i = 0; i < num; i++) et[i].cap -= et[i].flow;
        for(int i = 0; i < (int)mincut.size(); i++)
        {
            clearflow();
            int e = mincut[i];
            et[e].cap = C;
            int u = et[e].u, v = et[e].v;
            if(flow + isap(s, t, t + 1, C - flow) >= C) ans.push_back(pii(u, v));
            et[e].cap = 0;
        }
        if(ans.size() == 0)
        {
            printf("not possible\n");
            continue;
        }
        sort(ans.begin(), ans.end(), cmp);
        printf("possible option:");
        printf("(%d,%d)", ans[0].first, ans[0].second);
        for(int i = 1; i < (int)ans.size(); i++)
        printf(",(%d,%d)", ans[i].first, ans[i].second);
        puts("");
    }
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值