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();
}
}