A最小生成树
题意:有n个点的带权无向图,给出每个结点权值 , 该图为无向完全图,边值为点权值之和,问边权和最小的生成树为多少。
解法:贪心思想,因为是一棵树所以每个点至少被一条边连,让权值最小的点与其他所有点连边所构成的树权值和最小。
注意边界条件结点数为1。
#include<bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <string.h> #include <vector> typedef long long ll ; #define mod 80112002 #define gcd __gcd #define rep(i , j , n) for(int i = j ; i <= n ; i++) #define red(i , n , j) for(int i = n ; i >= j ; i--) #define ME(x , y) memset(x , y , sizeof(x)) //ll lcm(ll a , ll b){return a*b/gcd(a,b);} //ll quickpow(ll a , ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;b>>=1,a=a*a%mod;}return ans;} //int euler1(int x){int ans=x;for(int i=2;i*i<=x;i++)if(x%i==0){ans-=ans/i;while(x%i==0)x/=i;}if(x>1)ans-=ans/x;return ans;} //const int N = 1e7+9; int vis[n],prime[n],phi[N];int euler2(int n){ME(vis,true);int len=1;rep(i,2,n){if(vis[i]){prime[len++]=i,phi[i]=i-1;}for(int j=1;j<len&&prime[j]*i<=n;j++){vis[i*prime[j]]=0;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}else{phi[i*prime[j]]=phi[i]*phi[prime[j]];}}}return len} #define SC scanf #define INF 0x3f3f3f3f #define PI acos(-1) #define pii pair<int,int> #define fi first #define se second #define pb push_back #define mp make_pair #define all(v) v.begin(),v.end() #define size(v) (int)(v.size()) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define int ll using namespace std; const int N = 1e7+9; const int maxn = 1e5+9; int a[maxn]; void solve(){ int n , sum = 0; cin >> n ; int mi = INF ; rep(i , 1 , n){ cin >> a[i]; mi = min(mi , a[i]); sum += a[i]; } if(n == 1){ cout << 0 << endl; }else{ cout << sum + mi * (n-2) << endl; } } signed main() { //int _ ;cin>>_;while(_--) solve(); }
B病毒感染
题意:有给出n个点m条边的图,根据题目说明图不包含大于等于3的环,又是连通图所以可知该图去掉重边即为一棵树。找出城市,该城市到所有其他城市的距离和最短。可以知道该点就是树的重心。
重心:以该点为根的最大子树结点个数最少。
#include<bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <string.h> #include <vector> typedef long long ll ; #define mod 1000000009 #define gcd __gcd #define rep(i , j , n) for(int i = j ; i <= n ; i++) #define red(i , n , j) for(int i = n ; i >= j ; i--) #define ME(x , y) memset(x , y , sizeof(x)) //ll lcm(ll a , ll b){return a*b/gcd(a,b);} //ll quickpow(ll a , ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;b>>=1,a=a*a%mod;}return ans;} //int euler1(int x){int ans=x;for(int i=2;i*i<=x;i++)if(x%i==0){ans-=ans/i;while(x%i==0)x/=i;}if(x>1)ans-=ans/x;return ans;} //const int N = 1e7+9; int vis[n],prime[n],phi[N];int euler2(int n){ME(vis,true);int len=1;rep(i,2,n){if(vis[i]){prime[len++]=i,phi[i]=i-1;}for(int j=1;j<len&&prime[j]*i<=n;j++){vis[i*prime[j]]=0;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}else{phi[i*prime[j]]=phi[i]*phi[prime[j]];}}}return len} #define SC scanf #define INF 0x3f3f3f3f #define PI acos(-1) #define pii pair<int,int> #define fi first #define se second #define pb push_back #define mp make_pair #define all(v) v.begin(),v.end() #define size(v) (int)(v.size()) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define int ll using namespace std; const int N = 4e2+9; const int maxn = 5e4+9; vector<int>g[maxn]; map<int,map<int,int>>vis; int minSize , bal; int sz[maxn]; vector<int>v; int n , m ; void dfs(int u , int pre){ sz[u] = 1 ; int maxSub = 0 ; for(int v : g[u]){ if(v == pre) continue; dfs(v , u); sz[u] += sz[v]; maxSub = max(maxSub , sz[v]); } maxSub = max(maxSub , n-sz[u]); if(minSize > maxSub){ minSize = maxSub ; v.clear(); v.pb(u); }else if(minSize == maxSub){ v.pb(u); } } void solve(){ scanf("%lld%lld" , &n , &m); rep(i , 1 , m){ int u , v ; scanf("%lld%lld" , &u , &v); if(!vis[u][v]){ g[u].pb(v); g[v].pb(u); } vis[u][v] = 1 ; vis[v][u] = 1 ; } minSize = INF; dfs(1 , 0); for(auto i : v){ cout << i << " " ; } cout << endl; } signed main() { solve(); }
C:Shopping
题意:n件物品,表示物品价格,
表示物品是否为凳子,m个购物车,如果购物车有至少一个凳子则该购物车最贵物品半价。
解法:统计凳子数,购物车数与凳子数的最小值即为可半价商品数,让最贵商品半价。
#include<bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <string.h> #include <vector> typedef long long ll ; #define mod 80112002 #define gcd __gcd #define rep(i , j , n) for(int i = j ; i <= n ; i++) #define red(i , n , j) for(int i = n ; i >= j ; i--) #define ME(x , y) memset(x , y , sizeof(x)) //ll lcm(ll a , ll b){return a*b/gcd(a,b);} //ll quickpow(ll a , ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;b>>=1,a=a*a%mod;}return ans;} //int euler1(int x){int ans=x;for(int i=2;i*i<=x;i++)if(x%i==0){ans-=ans/i;while(x%i==0)x/=i;}if(x>1)ans-=ans/x;return ans;} //const int N = 1e7+9; int vis[n],prime[n],phi[N];int euler2(int n){ME(vis,true);int len=1;rep(i,2,n){if(vis[i]){prime[len++]=i,phi[i]=i-1;}for(int j=1;j<len&&prime[j]*i<=n;j++){vis[i*prime[j]]=0;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}else{phi[i*prime[j]]=phi[i]*phi[prime[j]];}}}return len} #define SC scanf #define INF 0x3f3f3f3f #define PI acos(-1) #define pii pair<int,int> #define fi first #define se second #define pb push_back #define mp make_pair #define all(v) v.begin(),v.end() #define size(v) (int)(v.size()) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define int ll using namespace std; const int N = 1e7+9; const int maxn = 1e3+9; int a[maxn]; bool cmp(int a , int b){ return a > b ; } void solve(){ int n , m , ans = 0; cin >> n >> m ; rep(i , 1 , n){ int x; cin >> a[i] >> x ; if(x)ans++; } double sum = 0; sort(a+1 , a+1+n , cmp); int k = min(ans , m); rep(i , 1 , k){ sum += 1.0*a[i]/2; } rep(i , k+1 , n){ sum += a[i]; } printf("%.1lf\n" , sum); } signed main() { int _ ;cin>>_;while(_--) solve(); }
D铺地毯
题意:n张地毯依次铺设在第一象限坐标轴上,给出每张地毯坐下坐标(a,b)及地毯在x轴和y轴方向的长度。问(x,y)点最上层的地毯标号,若没有地毯则输出-1.
解法:倒叙枚举判断(x,y)是否在第i块地毯区域。
#include<bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <string.h> #include <vector> typedef long long ll ; #define mod 80112002 #define gcd __gcd #define rep(i , j , n) for(int i = j ; i <= n ; i++) #define red(i , n , j) for(int i = n ; i >= j ; i--) #define ME(x , y) memset(x , y , sizeof(x)) //ll lcm(ll a , ll b){return a*b/gcd(a,b);} //ll quickpow(ll a , ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;b>>=1,a=a*a%mod;}return ans;} //int euler1(int x){int ans=x;for(int i=2;i*i<=x;i++)if(x%i==0){ans-=ans/i;while(x%i==0)x/=i;}if(x>1)ans-=ans/x;return ans;} //const int N = 1e7+9; int vis[n],prime[n],phi[N];int euler2(int n){ME(vis,true);int len=1;rep(i,2,n){if(vis[i]){prime[len++]=i,phi[i]=i-1;}for(int j=1;j<len&&prime[j]*i<=n;j++){vis[i*prime[j]]=0;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}else{phi[i*prime[j]]=phi[i]*phi[prime[j]];}}}return len} #define SC scanf #define INF 0x3f3f3f3f #define PI acos(-1) #define pii pair<int,int> #define fi first #define se second #define pb push_back #define mp make_pair #define all(v) v.begin(),v.end() #define size(v) (int)(v.size()) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define int ll using namespace std; const int N = 1e7+9; const int maxn = 1e4+9; struct node{ int a , b , x , y ; }a[maxn]; void solve(){ int n ; cin >> n ; rep(i , 1, n){ cin >> a[i].a >> a[i].b >> a[i].x >> a[i].y ; } int x , y ; cin >> x >> y ; red(i , n , 1){ if(x >= a[i].a && a[i].a + a[i].x >= x && y >= a[i].b && a[i].b+a[i].y >= y){ cout << i << endl; return ; } } } signed main() { //int _ ;cin>>_;while(_--) solve(); }
E金币馅饼
题意:给出n*m方格,每个方格有金币Ni , 从(1,1)走到到(n,m)所能捡到的最多金币为多少?
解法:dp[i][j]表示从(1,1)走到(i,j)所能捡到的最大金币数量。
#include<bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <string.h> #include <vector> typedef long long ll ; #define int ll #define mod 80112002 #define gcd __gcd #define rep(i , j , n) for(int i = j ; i <= n ; i++) #define red(i , n , j) for(int i = n ; i >= j ; i--) #define ME(x , y) memset(x , y , sizeof(x)) //ll lcm(ll a , ll b){return a*b/gcd(a,b);} //ll quickpow(ll a , ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;b>>=1,a=a*a%mod;}return ans;} //int euler1(int x){int ans=x;for(int i=2;i*i<=x;i++)if(x%i==0){ans-=ans/i;while(x%i==0)x/=i;}if(x>1)ans-=ans/x;return ans;} //const int N = 1e7+9; int vis[n],prime[n],phi[N];int euler2(int n){ME(vis,true);int len=1;rep(i,2,n){if(vis[i]){prime[len++]=i,phi[i]=i-1;}for(int j=1;j<len&&prime[j]*i<=n;j++){vis[i*prime[j]]=0;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}else{phi[i*prime[j]]=phi[i]*phi[prime[j]];}}}return len} #define SC scanf #define INF 0x3f3f3f3f #define PI acos(-1) #define pii pair<int,int> #define fi first #define se second #define pb push_back #define mp make_pair #define all(v) v.begin(),v.end() #define size(v) (int)(v.size()) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 using namespace std; const int N = 1e7+9; const int maxn = 1e3+9; int a[maxn][maxn]; int dp[maxn][maxn]; void solve(){ int n , m ; cin >> n >> m ; rep(i , 1 , n){ rep(j , 1 , m){ cin >> a[i][j]; } } dp[1][1] = a[1][1]; rep(j , 2 , m){ rep(i , 1 , n){ if(dp[i-1][j-1]){ dp[i][j] = max(dp[i][j] , dp[i-1][j-1] + a[i][j]); } if(dp[i][j-1]){ dp[i][j] = max(dp[i][j] , dp[i][j-1] + a[i][j]); } if(dp[i+1][j-1]){ dp[i][j] = max(dp[i][j] , dp[i+1][j-1]+a[i][j]); } } } cout << dp[n][m] << endl; } signed main() { //int _ ;cin>>_;while(_--) solve(); }