校內模擬測試010T1 刪點遊戲dt
阿新 • • 發佈:2020-11-05
題意簡述
n個點m條邊的無向圖,要把所有點一個一個地刪去。每次刪去一個點的花費為這個點相鄰的還未被刪除的點的點權。無重邊無自環,求最小代價。
資料範圍
對於\(30\%\)的資料\(n \le 10\)。
對於\(60\%\)的資料\(n,m \le 1000\)。
對於\(100\%\)的資料\(1\le n,m,a_i\le100000\)
分析
如果從點的角度來考慮,是無法得出貪心的結果的。考慮將點權轉化為邊權。
可以發現,最後每一條邊都是要被刪去的。刪掉一個點的代價是它的鄰點,而對於一條邊,我們肯定要貪心地讓其刪去的代價最小。故刪去一條邊的代價為連線的兩個點的最小值。
Code
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<map> #include<set> #include<queue> #include<vector> #define IL inline #define re register #define LL long long #define ULL unsigned long long #define re register #define debug printf("Now is %d\n",__LINE__); using namespace std; template<class T>inline void read(T&x) { char ch=getchar(); while(!isdigit(ch))ch=getchar(); x=ch-'0';ch=getchar(); while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} } inline int read() { int x=0; char ch=getchar(); while(!isdigit(ch))ch=getchar(); x=ch-'0';ch=getchar(); while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} return x; } int G[55]; template<class T>inline void write(T x) { int g=0; if(x<0) x=-x,putchar('-'); do{G[++g]=x%10;x/=10;}while(x); for(re int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n'); } LL n,m,ans; LL a[100010]; int main() { n=read(); m=read(); for(re LL i=1;i<=n;i++) a[i]=read(); for(re LL i=1;i<=m;i++) { ans+=min(a[read()],a[read()]); } cout<<ans; return 0; }