CodeForces 437C (貪心,拓撲排序)
阿新 • • 發佈:2018-12-30
題意:
給出一個n個點m條邊的圖,每個點有一個權值。每次分割出一個點,代價是該點相鄰點的權值和,問分割所有的點最小的代價是多少。
思路:
建成有向圖,方向從權值大的點指向權值小的點,邊權為兩個點權中小的那個。
然後從入度最小的點開始分割,邊分割邊修改入度,一直取入度最小的點分割即可。
程式碼:
#include <iostream> #include <iomanip> #include <algorithm> #include <cstring> #include <cctype> #include <cstdlib> #include <cstdio> #include <cmath> #include <ctime> #include <map> #include <list> #include <set> #include <stack> #include <queue> #include <string> #include <sstream> #define pb push_back #define X first #define Y second #define ALL(x) x.begin(),x.end() #define INS(x) inserter(x,x.begin()) #define pii pair<int,int> #define qclear(a) while(!a.empty())a.pop(); #define lowbit(x) (x&-x) #define sd(n) scanf("%d",&n) #define sdd(n,m) scanf("%d%d",&n,&m) #define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k) #define mst(a,b) memset(a,b,sizeof(a)) #define cout3(x,y,z) cout<<x<<" "<<y<<" "<<z<<endl #define cout2(x,y) cout<<x<<" "<<y<<endl #define cout1(x) cout<<x<<endl #define IOS std::ios::sync_with_stdio(false) #define SRAND srand((unsigned int)(time(0))) typedef long long ll; typedef unsigned long long ull; typedef unsigned int uint; using namespace std; const double PI=acos(-1.0); const int INF=0x3f3f3f3f; const ll mod=998244353; const double eps=1e-8; const int maxn=1005; const int maxm=2005; int T; int n,m; int cost[maxn]; vector<pii>maps[maxn]; vector<int>indeg[maxm]; int in[maxn]; bool vis[maxn]; void solve() { sdd(n,m); for(int i=1;i<=n;i++){ sd(cost[i]); } mst(in,0); for(int i=0;i<m;i++){ int u,v; sdd(u,v); if(cost[u]>cost[v])swap(u,v); maps[v].pb(make_pair(u,cost[u])); in[u]++; } for(int i=1;i<=n;i++){ indeg[in[i]].pb(i); } mst(vis,0); int ans=0; while(1){ int cnt=0; for(int i=0;;i++){ for(int j=0;j<indeg[i].size();j++){ int now=indeg[i][j]; if(vis[now])continue; vis[now]=1; cnt++; for(int k=0;k<maps[now].size();k++){ int temp=maps[now][k].X; in[temp]--; indeg[in[temp]].pb(temp); ans+=maps[now][k].Y; } if(cnt==n)break; } if(cnt==n)break; } if(cnt==n)break; } printf("%d\n",ans); return ; } int main() { #ifdef LOCAL freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #else // freopen("","r",stdin); // freopen("","w",stdout); #endif solve(); return 0; }