作者 胡伟平
单位 广西科技大学
胡老师买了新房,正在搞装修,装修公司太坑了,于是胡老师就自己找装修师傅来干活,但是装修的很多环节是环环相扣的,比如,要先刷墙才能铺木地板,有些环节呢,又是互相不干扰的,比如厨房的装修和窗帘的安装。但是每个装修师傅的时间又受他接的单所限制。所以必须仔细安排才能把房子装修好。胡老师收到了若干种不同装修师傅的安排,他想尽快装修好了入住,你能帮他吗?
输入格式:
第一行输入正整数T(T< 20),表示有T个方案,对于每一个方案,第一行输入两个正整数N(< 100)和M,其中N是装修时间点的个数,从0开始编号,M是装修环节的个数。随后M行,每行输入三个非负整数表示一个装修环节,Start End Delay,Start表示开始时间点编号,End表示结束时间点编号,Delay表示装修需要时间。
输出格式:
对每一个方案,如果方案可行,则在一行里输入最早结束的时间,如果不可行,则输出Impossible!。
输入样例:
在这里给出一组输入。例如:
2
7 10
0 1 3
0 2 2
0 3 6
1 3 2
2 3 1
1 4 4
3 4 1
2 5 3
4 6 3
5 6 4
3 3
0 1 1
1 2 2
2 0 3
输出样例:
在这里给出相应的输出。例如:
10
Impossible!
经典的拓扑排序,但这里有一个注意点,一个房间最快完成时间不取决于最快在这个房间的步骤,而是最晚完成的步骤。
例如:在没有前置任务的情况下完成房间地板安装需要10分钟,窗户安装8分钟,刷墙5分钟,那么这个房间最快完成时间就是10分钟。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl "\n"
ll n,m,sum,cnt;
ll v[1007],js[1007];//入度,房间最早结束时间
map<ll,map<ll,ll> >mp;
queue<ll>q;
vector<ll>lian[1007];
void tp(){
while(!q.empty()){
ll x=q.front();//当前装修到哪个房间
//当前房间的最晚时间,前一个房间的最晚时间+此步骤装修房间所需时间
for(auto it : mp[x])js[x]=max(js[x],js[it.first]+it.second);
cnt=max(cnt,js[x]);1
q.pop();//以下为拓扑模板
for(ll i = 0 ; i < lian[x].size() ; i ++){
v[lian[x][i]]--;
if(v[lian[x][i]] == 0){
sum++;
q.push(lian[x][i]);
}
}
}
}
void solve(){
cin >> n >> m;
memset(v,0,sizeof v);//初始化
for(ll i = 0 ; i < n ; i ++)lian[i].clear();
while(!q.empty())q.pop();mp.clear();
while(m --){
ll x,y,z;
cin >> x >> y >> z;
mp[y][x]=z;//注意,是先完成x房间再完成y房间
v[y]++;//拓扑的入度++
lian[x].push_back(y);//建立拓扑的链表
}
sum=0,cnt=0;
for(ll i = 0 ; i < n ; i ++)
if(!v[i])q.push(i),sum++;
memset(js,0,sizeof js);
tp();
if(sum < n)cout << "Impossible!" << endl;
else cout << cnt << endl;
return;
}
int main(){
ll t=1;cin >> t;
while(t--)solve();
return 0;
}
文章讲述了作者胡伟平面临新房装修问题,如何通过使用拓扑排序算法合理安排多个装修师傅的工作,确保所有环节按顺序完成,同时考虑每个环节的延迟,以尽早完成整个装修过程。
1412

被折叠的 条评论
为什么被折叠?



