ASC7 Problem H. Oil Deal

题目大意

给个带边权图,求给定代价内最多删多少条边任然存在生成树。

简要题解

先做个最大生成树,然后从小往大删不在树上的边即可。

 

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 namespace my_header {
  4 #define pb push_back
  5 #define mp make_pair
  6 #define pir pair<int, int>
  7 #define vec vector<int>
  8 #define pc putchar
  9 #define clr(t) memset(t, 0, sizeof t)
 10 #define pse(t, v) memset(t, v, sizeof t)
 11 #define bl puts("")
 12 #define wn(x) wr(x), bl
 13 #define ws(x) wr(x), pc(' ')
 14     const int INF = 0x3f3f3f3f;
 15     typedef long long LL;
 16     typedef double DB;
 17     inline char gchar() {
 18         char ret = getchar();
 19         for(; (ret == '\n' || ret == '\r' || ret == ' ') && ret != EOF; ret = getchar());
 20         return ret; }
 21     template<class T> inline void fr(T &ret, char c = ' ', int flg = 1) {
 22         for(c = getchar(); (c < '0' || '9' < c) && c != '-'; c = getchar());
 23         if (c == '-') { flg = -1; c = getchar(); }
 24         for(ret = 0; '0' <= c && c <= '9'; c = getchar())
 25             ret = ret * 10 + c - '0';
 26         ret = ret * flg; }
 27     inline int fr() { int t; fr(t); return t; }
 28     template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); }
 29     template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); }
 30     template<class T> inline char wr(T a, int b = 10, bool p = 1) {
 31         return a < 0 ? pc('-'), wr(-a, b, 0) : (a == 0 ? (p ? pc('0') : p) : 
 32             (wr(a/b, b, 0), pc('0' + a % b)));
 33     }
 34     template<class T> inline void wt(T a) { wn(a); }
 35     template<class T> inline void wt(T a, T b) { ws(a), wn(b); }
 36     template<class T> inline void wt(T a, T b, T c) { ws(a), ws(b), wn(c); }
 37     template<class T> inline void wt(T a, T b, T c, T d) { ws(a), ws(b), ws(c), wn(d); }
 38     template<class T> inline T gcd(T a, T b) {
 39         return b == 0 ? a : gcd(b, a % b); }
 40     template<class T> inline T fpw(T b, T i, T _m, T r = 1) {
 41         for(; i; i >>= 1, b = b * b % _m)
 42             if(i & 1) r = r * b % _m;
 43         return r; }
 44 };
 45 using namespace my_header;
 46 
 47 const int MAXN = 50000 + 100;
 48 const int MAXM = 100000 + 100;
 49 struct Edge {
 50     int u, v, w, id, blp;
 51     void read() {
 52         fr(u, v, w);
 53     }
 54     bool operator < (const Edge&rhs) const {
 55         return w < rhs.w;
 56     }
 57 } e[MAXM];
 58 LL n, m, s;
 59 
 60 int fa[MAXN];
 61 int findFa(int u) {
 62     return fa[u] == u ? u : fa[u] = findFa(fa[u]);
 63 }
 64 
 65 int main() {
 66 #ifdef lol
 67     freopen("H.in", "r", stdin);
 68     freopen("H.out", "w", stdout);
 69 #else
 70     freopen("oil.in", "r", stdin);
 71     freopen("oil.out", "w", stdout);
 72 #endif
 73     fr(n, m, s);
 74     for (int i = 1; i <= m; ++i) {
 75         e[i].read();
 76         e[i].id = i;
 77     }
 78     sort(e + 1, e + m + 1);
 79     for (int i = 1; i <= n; ++i)
 80         fa[i] = i;
 81     for (int i = m; 0 < i; --i) {
 82         int u = findFa(e[i].u);
 83         int v = findFa(e[i].v);
 84         if (u != v) {
 85             fa[u] = v;
 86             e[i].blp = true;
 87         }
 88     }
 89     vector<int> res;
 90     for (int i = 1; i <= m; ++i) {
 91         if (s - e[i].w >= 0 && !e[i].blp) {
 92             s -= e[i].w;
 93             res.pb(e[i].id);
 94         }
 95     }
 96     wt(res.size());
 97     for (auto &&i : res) {
 98         ws(i);
 99     }
100     bl;
101 
102 
103     return 0;
104 }

 

转载于:https://www.cnblogs.com/ichn/p/6406609.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值