2024SMUSpring天梯3非补题
L2-1:哈利·波特的考试
题意:
思路:建图跑dijkstra即可。
int n,m,ans1=0,ans2=INT_MAX;
const int inf=0x3f3f3f3f;
vector<PII> vct[150];
priority_queue<PII> pq;
int dis[150],vis[150];
void dijkstra(int s){
//memset(dis,inf,sizeof(dis));
for(int i=1;i<=n;i++) dis[i]=inf;
memset(vis,0,sizeof(vis));
dis[s]=0;
pq.emplace(0,s);
while(pq.size()){
int from=pq.top().second;
pq.pop();
if(vis[from]) continue;
vis[from]=1;
for(auto v:vct[from]){
int to=v.first,weight=v.second;
if(dis[from]+weight<dis[to]){
dis[to]=dis[from]+weight;
pq.emplace(-dis[to],to);
}
}
}
}
void solve(){ //L2-1
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
vct[u].emplace_back(v,w);
vct[v].emplace_back(u,w);
}
for(int i=1;i<=n;i++) {
dijkstra(i);
int maxdis=0;
for(int j=1;j<=n;j++) maxdis=max(maxdis,dis[j]);
if(maxdis==inf){
cout<<"0";
return;
}
if(maxdis<ans2) ans1=i,ans2=maxdis;
}
cout<<ans1<<" "<<ans2;
}
L2-2:列车厢调度
题意:
思路:简单模拟题,跟货架搬箱子一题一样思路。模拟即可。
void solve(){ //L2-2
stack<char> stk1,stk2,stk3;
string str1; cin>>str1;
reverse(str1.begin(),str1.end());
string str2; cin>>str2;
reverse(str2.begin(),str2.end());
for(int i=0;i<str1.size();i++) stk1.emplace(str1[i]);
for(int i=0;i<str2.size();i++) stk2.emplace(str2[i]);
vector<string> ans;
while(stk1.size()){
if(stk1.top()==stk2.top()){
ans.emplace_back("1->2");
stk1.pop(),stk2.pop();
}
else if(stk3.size()&&stk3.top()==stk2.top()){
while(stk2.size()&&stk3.size()&&stk3.top()==stk2.top()){
ans.emplace_back("3->2");
stk2.pop(),stk3.pop();
}
}
else{
ans.emplace_back("1->3");
stk3.emplace(stk1.top());
stk1.pop();
}
}
while(stk2.size()&&stk3.size()&&stk3.top()==stk2.top()){
ans.emplace_back("3->2");
stk2.pop(),stk3.pop();
}
if(stk3.size()||stk2.size()) cout<<"Are you kidding me?";
else {
for(auto a:ans) cout<<a<<endl;
}
}
L2-3:文件传输
题意:
思路:经典并查集,没什么难点。
int fa[10004];
int find(int x){
if(x!=fa[x]) fa[x]=find(fa[x]);
return fa[x];
}
void Union(int x,int y){
int fa1=find(x),fa2=find(y);
fa[fa2]=fa1;
}
void solve(){ //L2-3--并查集
int n; cin>>n;
for(int i=1;i<=n;i++) fa[i]=i;
char op;
while(1){
cin>>op;
if(op=='S') break;
int u,v;
cin>>u>>v;
if(op=='I'&&find(u)!=find(v)) Union(u,v);
else if(op=='C'){
if(find(u)==find(v)) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
}
unordered_set<int> st; //数并查集个数,学来的
for(int i=1;i<=n;i++) st.insert(find(i));
if(st.size()==1) cout<<"The network is connected.";
else cout<<"There are "<<st.size()<<" components.";
}
L2-4:病毒溯源
题意:
思路:建图dfs,回溯记录路径即可。
int n,root,maxDepth=1,road[10004];
unordered_map<int,bool> mp;
vector<int> vct[10004];
void dfs1(int x,int depth){
if(vct[x].size()==0) maxDepth=max(maxDepth,depth);
for(auto v:vct[x]) dfs1(v,depth+1);
}
//bool check=false; //check==true时,记录回溯的路径
//stack<int> ans;
bool dfs2(int x,int depth){
if(depth==maxDepth) return true;
bool res=false;
for(auto v:vct[x]) {
if( dfs2(v,depth+1) ){
if(v<road[x]) road[x]=v;
res=true;
}
}
return res;
}
void solve(){ //L2-4 剩31min
cin>>n;
for(int i=0;i<n;i++){
int k; cin>>k;
for(int j=1;j<=k;j++){
int x; cin>>x;
vct[i].emplace_back(x);
mp[x]=1;
}
}
for(int i=0;i<n;i++){ //找到根源
if(!mp[i]){
root=i;
break;
}
}
dfs1(root,1);
//for(int i=0;i<n;i++) sort(vct[i].begin(),vct[i].end()); //优先走小的突变,第一个走到maxDepth的即是答案路径
for(int i=0;i<n;i++) road[i]=INT_MAX;
dfs2(root,1);
cout<<maxDepth<<endl;
cout<<root;
int cur=root;
while(road[cur]!=INT_MAX){
cout<<" "<<road[cur];
cur=road[cur];
}
// ans.emplace(root);
// while(ans.size()){
// cout<<ans.top();
// if(ans.size()!=1) cout<<" ";
// ans.pop();
// }
}