TC srm 632 div1

Problem Statement

    
Alice is going to host a competition in running, called the Candy Cup. Candy Cup will take place in a city that consists of N intersections. The intersections are numbered 0 through N-1.

There are M roads in the city. The roads are numbered 0 through M-1. Each road is bidirectional and connects two intersections. There are no self-loops. Each pair of intersections is directly connected by at most one road. Note that the road network is not guaranteed to be connected. (That is, it may be impossible to travel between some pairs of intersections.)


You are given the description of the city: the int N and two vector <int>s A and B, each with M elements. For each valid i, the road number i connects the intersections A[i] and B[i].

As a preparation for the Candy Cup, Alice has placed some candies into the middle of each road. For each i, she placed exactly 3^i (three to the power of i) candies into the middle of road i.

The rules of Candy Cup are really simple. Each participant starts at the intersection 0 and must reach intersection N-1 by following some roads. Additionally, each time a participant takes a road, they must pick up a candy from that road. (Once there are no candies left on a road, participants in the race are not allowed to take that road.) Note that different participants may use a different number of roads to reach the finish.

Let F be the largest possible number of participants that can finish Candy Cup by reaching the finish in a valid way. Return the value (F modulo 1,000,000,007).
Definition
    
Class:
CandyCupRunningCompetition
Method:
findMaximum
Parameters:
int, vector <int>, vector <int>
Returns:
int
Method signature:
int findMaximum(int N, vector <int> A, vector <int> B)
(be sure your method is public)
Limits
    
Time limit (s):
2.000
Memory limit (MB):
256
Constraints
-
N will be between 2 and 2000, inclusive.
-
A and B will contain between 0 and 2,000 elements, inclusive.
-
A and B will each contain the same number of elements.
-
Each element of A and B will be between 0 and N-1, inclusive.
-
No two roads will connect the same pair of intersections.
-

For each valid i, A[i] will be different from B[i].

題目大意:給你n個點,編號爲0~n-1,m條邊,邊有編號從0~m-1,編號爲i的邊,邊權爲3^i。然後問你從0號節點到n-1號節點的最大流!!

解題思路:很明顯是一個最大流,但是n最大爲2000,邊最多有4*10^6,顯然網絡流根本跑不出來,(師兄說,如果邊比較少,有可能跑出來。。。)然後,某神牛給了一個思路是貪心!!怎麼貪心,完全想不到啊。。。。因爲權值是離散的(這個我也知道,但是有什麼用呢?),將邊權從大往小掃描,如果加入當前的邊,使得0和n-1連通,那麼這條邊一定是最小割的一條邊(可以證明在這條邊之前加入的邊,權值至少是這條邊的3倍!肯定用不完);否則將這條邊加入並查集!

詳見代碼,思路真是太神了!!

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define ll long long
#define db double
#define PB push_back
using namespace std;

const int N = 100005;
const ll MOD = 1000000007;

class CandyCupRunningCompetition
{
private:
    vector<int> fa;
    void init(int n)
    {
        for(int i=0;i<n;i++) fa.PB(i);
    }
    int find_fa(int r)
    {
        if(fa[r]==r) return r;
        return fa[r]=find_fa(fa[r]);
    }
    void unio(int i,int j)
    {
        fa[find_fa(i)]=find_fa(j);
    }
    ll quick_pow(int k)
    {
        ll res=1LL;
        ll t=3;
        while(k>0)
        {
            if(k&1) res=(res*t)%MOD;
            t=(t*t)%MOD;
            k>>=1;
        }
        return res;
    }
public:
    int findMaximum(int n, vector <int> a, vector <int> b)
    {
        fa.clear();
        init(n);
        ll ans=0LL;
        for(int i=a.size()-1;i>=0;i--)
        {
            vector<int> bf=fa;
            unio(a[i],b[i]);
            if(find_fa(0)==find_fa(n-1))
            {
                ans=(ans+quick_pow(i))%MOD;
                fa=bf;
            }
        }
        return (int)ans;
    }
} tmp;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章