思路
这题是Easy版本,只有一个发电站耗电量不确定,所以只需要统计与这个发电站直接相连的发电站的耗电量。
因为是要异或和最小,所以这里我统计了与未知发电站直接相连的发电站功耗的贡献,如果某一位1的个数大于0的个数那耗电量在这意味就是1。(异或让贡献尽可能小)
其他的直接暴力算就好,要注意电缆的消耗因为算了两次所以最后的答案要除2
代码
#pragma GCC target("avx,sse2,sse3,sse4,popcnt") #pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math") #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) inline void write(__int128 x) { if (!x) { putchar('0'); return; } char F[50]; __int128 tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } #define pb push_back #define pll pair<ll,ll> #define INF 0x3f3f3f3f const int mod = 1e9+7; const int maxn = 100005; inline ll read(){ ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } ll w[505]; vector<int> q[505]; int num[35]; int main(){ int n = read(),m = read(); int st; for(int i = 1 ;i <= n ; ++i){ w[i] = read(); if(w[i] == -1) st = i;//记录未知功耗发电站位置 } while(m--){ int u = read(),v = read();//建图 q[u].pb(v); q[v].pb(u); } for(int i = 0 ; i < q[st].size() ; ++i){//统计位置功耗发电站直接连接的数的贡献 for(int j = 0 ; j < 32 ; ++j){ num[j] += ((w[q[st][i]]>>j)&1); } } ll cnt = 0; for(int i = 31 ; i >= 0 ; --i){//计算位置功耗发电站的功耗 cnt = cnt << 1; if(num[i] > q[st].size() - num[i]) cnt += 1; } w[st] = cnt; __int128 ans = 0;cnt = 0; for(int i = 1 ; i <= n ; ++i){ cnt += w[i];//所有发电站功耗 for(int j = 0 ; j < q[i].size() ; ++j){ ans += w[i]^w[q[i][j]];//电缆功耗 } } write(ans/2);putchar(10); cout<<cnt<<endl; }