PAT* 1001 Battle Over Cities - Hard Version (35 分)(最小生成树)

这题难度在于读题。。实际上就是对于每个点暴力计算最小花费然后比较即可。计算最小花费用克鲁斯卡尔,先用完整的路再用废弃的路即可。注意若最终仍然不能连通则花费为INF。


#define gcd(a, b) __gcd(a, b)
#define INF 0x3f3f3f3f3f
#define eps 1e-6
#define PI acos(-1.0)
#define pb push_back
#define fst first
#define sec second
#define eif else if
#define de(x) cout << x << ' '
#define en cout << '\n'
#define fuck cout << "fuck\n"
#define rep(i, x, y) for (int i = x; i < y; i++)
#define red(i, x, y) for (int i = x - 1; i >= y; i--)
#define mem(a, x) memset(a, x, sizeof(a))
#define IOS cin.tie(0), ios::sync_with_stdio(false)
#define maxn 200005
#define mod 1000000007
typedef long long ll;
#define pll pair<ll, ll>
using namespace std;
ll qpow(ll a, ll b) {
    ll ans = 1;
    for (; b; b >>= 1) {
        if (b & 1)
            ans = ans * a % mod;
        a = a * a % mod;
    }
    return ans;
}
#define N 1005
#define M 200005
int n, m;

struct edge {
    int u, v, w, s;
    bool operator < (const edge& o) const {
        return w < o.w;
    }
};
vector<edge> e1, e2;
int fa[N];
int get(int x) {
    if(x == fa[x]) return x;
    return fa[x] = get(fa[x]);
}
void solve() {
    cin >> n >> m;
    for(int i = 1; i <= m; i++) {
        int u, v, w, s;
        cin >> u >> v >> w >> s;
        edge tmp = {u, v, w, s};
        if(s == 1) e1.push_back(tmp);
        else e2.push_back(tmp);
    }
    sort(e1.begin(), e1.end());
    sort(e2.begin(), e2.end());
    vector<pair<int,int> > city;
    int mxcost = 0;
    for(int i = 1; i <= n; i++) {
        int cost = 0;
        rep(j, 1, n + 1) fa[j] = j;
        int cnt = 0;
        for(auto x : e1) {
            if(x.u == i || x.v == i) continue;
            int fu = get(x.u), fv = get(x.v);
            if(fu == fv) continue;
            fa[fu] = fv;
            cnt++;
        }
        if(cnt >= n - 2) continue;
        for(auto x : e2) {
            if(x.u == i || x.v == i) continue;
            int fu = get(x.u), fv = get(x.v);
            if(fu == fv) continue;
            fa[fu] = fv;
            cnt++;
            cost += x.w;
        }
        if(cnt >= n - 2) {
            city.push_back(make_pair(i, cost));
            mxcost = max(mxcost, cost);
        } else {
            city.push_back(make_pair(i, 0x3f3f3f3f));
            mxcost = max(mxcost, 0x3f3f3f3f);
        }
        //cout << i << " " << cost << endl;
    }
    vector<int> ans;
    if(mxcost == 0) cout << 0;
    else {
        for(auto x : city) {
            if(x.second == mxcost) ans.push_back(x.first);
        }
    }
    for(int i = 0; i < ans.size(); i++) {
        if(i == ans.size() - 1) cout << ans[i];
        else cout << ans[i] << " ";
    }
}
signed main() {
    int T = 1;
    //cin >> T;
    while (T--) {
        solve();
    }
}
上一篇:c# – 有没有办法用NLog创建一个命名的记录器并通过这个名称过滤记录?


下一篇:wqs二分