图论啥的都不会了,还有救吗?
USACO的第一个测试点是样例,可以骗分的……
A.公路通行税
link
这题就是找出图中的最长不重复的道路
在注意到$1 \leq n \leq 10^3$,想也不用想就可以排除掉Floyd
由于每个道路的长度都是$1$,所以就可以直接bfs。
注意多测清空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
#include<bits/stdc++.h> using namespace std; const int MAXN=1010; vector <int> g[MAXN]; int n,m,ans; bool vis[MAXN]; void bfs(int s) { queue <pair<int,int>> q; q.push({s,0}); vis[s]=1; while(!q.empty()) { int u=q.front().first,dis=q.front().second; ans=max(ans,dis); q.pop(); for(auto v:g[u]) if(!vis[v]) vis[v]=1,q.push({v,dis+1}); } } void solve() { ans=-1; for(int i=1;i<=n;i++)g[i].clear(); for(int i=1;i<=m;i++) { int u,v; cin>>u>>v; g[u].push_back(v); g[v].push_back(u); } for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); bfs(i); } cout<<ans*100<<'\n'; } int main() { while(1) { cin>>n>>m; if(n&&m)solve(); else break; } return 0; }
|
B. [USACO22OPEN] Visits S
link
这题想亻乙想就知道这题的答案就是非环部分的叫声总和加上环上部分总和减去环上部分的最小值(因为绕一圈回来肯定有一个去朋友家了,所以贪心舍弃最小值)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
#include<bits/stdc++.h> using namespace std; const int MAXN=200010; #define int long long int a[MAXN],v[MAXN],indeg[MAXN],n,ans,minn=LLONG_MAX; bool vis[MAXN]; void topo() { queue <int> q; for(int i=1;i<=n;i++) if(!indeg[i])q.push(i); while(!q.empty()) { int u=q.front(); q.pop(); ans+=v[u]; vis[u]=1; indeg[a[u]]--; if(!indeg[a[u]])q.push(a[u]); } } void dfs(int u) { vis[u]=1; minn=min(minn,v[u]); if(!vis[a[u]])dfs(a[u]); } signed main() { cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]>>v[i]; indeg[a[i]]++; } topo(); for(int i=1;i<=n;i++) if(!vis[i])ans+=v[i]; for(int i=1;i<=n;i++) if(!vis[i]) { minn=LLONG_MAX; dfs(i); ans-=minn; } cout<<ans; return 0; }
|
C. [USACO3.1] 丑数 Humble Numbers
这题一看就是一种恶心人的数学
可以用多次乘来得到第$n$小的丑数
怎么做呢?
先假设$1$是丑数,然后再用指针记录,分别乘$S$中的数,接下来对指针进行更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
#include<bits/stdc++.h> using namespace std; #define int long long int a[110],f[114514],idx[110]; signed main() { int k,n; cin>>k>>n; for(int i=1;i<=k;i++)cin>>a[i]; f[0]=1; for(int i=1;i<=n;i++) { int minn=LLONG_MAX; for(int j=1;j<=k;j++) minn=min(minn,f[idx[j]]*a[j]); f[i]=minn; for(int j=1;j<=k;j++) if(f[idx[j]]*a[j]==minn) idx[j]++; } cout<<f[n]; return 0; }
|
原先用stl做的超时了……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
#include<bits/stdc++.h> using namespace std; #define int long long set <int> st; priority_queue <int,vector <int>,greater<int> > q; int a[100010]; signed main() { int k,n; scanf("%lld%lld",&k,&n); for(int i=1;i<=k;i++)scanf("%lld",&a[i]); q.push(1); st.insert(1); int cnt=0,front; while(cnt<=n) { cnt++; front=q.top(); q.pop(); for(int j=1;j<=k;j++) { int num=front*a[j]; if(!st.count(num)) { q.push(num); st.insert(num); } } } printf("%d",front); return 0; }
|
D. [TJOI2013] 黄金矿工
link
这题的数据非常💧,导致01背包的模板都能过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
#include<bits/stdc++.h> using namespace std; const int MAXN=210; int v[MAXN],w[MAXN],dp[40010],t,n; int main() { cin>>n>>t; for(int i=1;i<=n;i++) { int tmp; cin>>tmp>>tmp>>v[i]>>w[i]; } for(int i=1;i<=n;i++) for(int j=t;j>=v[i];j--) dp[j]=max(dp[j],dp[j-v[i]]+w[i]); cout<<dp[t]; return 0; }
|
《天津省选》
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
#include<bits/stdc++.h> using namespace std; struct node { int x,y,t,v; double b; }pos[2010]; bool cmp(node a,node b) { if(a.b==b.b)return a.y<b.y; return a.b<b.b; } int n,T,gold[2010],t[2010][2010],v[2010][2010],f[40010],cnt; int main() { cnt=0; cin>>n>>T; for(int i=1;i<=n;i++) { cin>>pos[i].x>>pos[i].y>>pos[i].t>>pos[i].v; pos[i].b=pos[i].y*1.0/pos[i].x; } sort(pos+1,pos+1+n,cmp); for(int i=1;i<=n;i++) { if(i==1||pos[i].b!=pos[i-1].b)cnt++; if(gold[cnt]==0) { gold[cnt]=1; t[cnt][1]=pos[i].t; v[cnt][1]=pos[i].v; } else { gold[cnt]++; t[cnt][gold[cnt]]=t[cnt][gold[cnt]-1]+pos[i].t; v[cnt][gold[cnt]]=v[cnt][gold[cnt]-1]+pos[i].v; } } memset(f,0,sizeof(f)); for(int i=1;i<=cnt;i++) for(int j=T;j>=t[i][1];j--) { int maxn=f[j]; for(int k=1;k<=gold[i];k++) if(j>=t[i][k]) maxn=max(maxn,f[j-t[i][k]]+v[i][k]); f[j]=maxn; } cout<<f[T]; return 0; }
|