• E. Speedrun


    Problem - E - Codeforces

    思路:分析题意知给定的图一定是一个有向无环图,所以能够使用拓扑序,在进行拓扑排序的途中统计一个维护一个完成当前任务的最小时间,那么入度为零的点就是一开始的时间,其他的点就是统计所有前驱的最大值max,表示至少在这个最大值之后它才能够完成这个任务,然后我们在看一下max%k与w[u]的关系,如果是大于关系,则代表要完成w[u]必须要到下一天了,因为这一天已经是max%k了,已经比w[u]大了;如果是小于关系,那么能够在这一天完成这个任务。那么我们现在就得到了每个点能够完成的最小的时间,那么统计最大值以及最小值相减就是答案吗?不是的,因为我们通过样例能够发现,我们可以讲某个入度为零的点延后一天完成,这样就使得最小值变大了,但是可能最大值会增加一点点,这样就能够使得差值变小了,那么我们能否枚举所有的入度为零的点,从小到达枚举,然后讲它们延后一天,统计出延后之后的最大值,然后减去最小值呢?这样做是可以的,我们发现每个点最多只会被延后一天(因为假如说u为当前的点,j为其前驱节点,那么如果其中某个j延后了一天,对于u来说,有两种情况,如果延后一天之后也不比它大,说明我u不用延后保持原来的即可,如果延后之后比它大了,说明我必须要延后一天了。但是出现了第二中状态以后,就不会再出现第二种状态了,因为原先u的完成时间是比所有的j都大的,那么如果u+k,那么对于所有的j来说,j+k一定也不会比u+k大了,所有一定是满足条件了,所以每个点最多只会被延后一天,所以每个节点最多只会被遍历一次),那么这样我们就能够保证修改的时间复杂度了,所以就可以直接暴力枚举了

    1. // Problem: E. Speedrun
    2. // Contest: Codeforces - Pinely Round 2 (Div. 1 + Div. 2)
    3. // URL: https://codeforces.com/contest/1863/problem/E
    4. // Memory Limit: 256 MB
    5. // Time Limit: 2000 ms
    6. #include
    7. #include
    8. #include
    9. #define fi first
    10. #define se second
    11. #define i128 __int128
    12. using namespace std;
    13. typedef long long ll;
    14. typedef double db;
    15. typedef pair<int,int> PII;
    16. const double eps=1e-7;
    17. const int N=5e5+7 ,M=5e5+7, INF=0x3f3f3f3f,mod=1e9+7,mod1=998244353;
    18. const long long int llINF=0x3f3f3f3f3f3f3f3f;
    19. inline ll read() {ll x=0,f=1;char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
    20. while(c>='0'&&c<='9') {x=(ll)x*10+c-'0';c=getchar();} return x*f;}
    21. inline void write(ll x) {if(x < 0) {putchar('-'); x = -x;}if(x >= 10) write(x / 10);putchar(x % 10 + '0');}
    22. inline void write(ll x,char ch) {write(x);putchar(ch);}
    23. void stin() {freopen("in_put.txt","r",stdin);freopen("my_out_put.txt","w",stdout);}
    24. bool cmp0(int a,int b) {return a>b;}
    25. template<typename T> T gcd(T a,T b) {return b==0?a:gcd(b,a%b);}
    26. template<typename T> T lcm(T a,T b) {return a*b/gcd(a,b);}
    27. void hack() {printf("\n----------------------------------\n");}
    28. int T,hackT;
    29. int n,m,k;
    30. int w[N];
    31. int h[N],e[M],ne[M],idx;
    32. ll dist[N];
    33. int din[N];
    34. vector<int> son[N];
    35. ll maxn=-1;
    36. void add(int a,int b) {
    37. e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    38. }
    39. void topsort() {
    40. queue<int> q;
    41. for(int i=1;i<=n;i++) {
    42. if(!din[i]) q.push(i);
    43. }
    44. while(q.size()) {
    45. auto it=q.front();
    46. q.pop();
    47. if(son[it].size()==0) dist[it]=w[it];
    48. else {
    49. ll sum=0;
    50. for(int i=0;isize();i++) {
    51. int j=son[it][i];
    52. sum=max(sum,dist[j]);
    53. }
    54. if((sum%k)<=w[it]) sum+=w[it]-(sum%k);
    55. else sum+=k-(sum%k)+w[it];
    56. dist[it]=sum;
    57. }
    58. for(int i=h[it];i!=-1;i=ne[i]) {
    59. int j=e[i];
    60. din[j]--;
    61. if(din[j]==0) q.push(j);
    62. }
    63. }
    64. }
    65. void dfs(int u,ll &maxn) {
    66. dist[u]=dist[u]+k;
    67. maxn=max(maxn,dist[u]);
    68. for(int i=h[u];i!=-1;i=ne[i]) {
    69. int j=e[i];
    70. if(dist[j]>=dist[u]) continue;
    71. else dfs(j,maxn);
    72. }
    73. }
    74. void solve() {
    75. n=read(),m=read(),k=read();
    76. memset(h,-1,sizeof(int)*(n+4));
    77. memset(din,0,sizeof(int)*(n+4));
    78. idx=0;
    79. for(int i=1;i<=n;i++) w[i]=read(),son[i].clear(),dist[i]=0;
    80. maxn=-1;
    81. while(m--) {
    82. int a=read(),b=read();
    83. add(a,b);
    84. son[b].push_back(a);
    85. din[b]++;
    86. }
    87. vector<int> vis;
    88. for(int i=1;i<=n;i++) if(!din[i]) vis.push_back(i);
    89. topsort();
    90. for(int i=1;i<=n;i++) maxn=max(maxn,dist[i]);
    91. sort(vis.begin(),vis.end(),[&](int &a,int &b){
    92. return w[a]
    93. });
    94. ll res=llINF;
    95. res=min(res,maxn-dist[vis[0]]);
    96. for(int i=0;isize()-1;i++) {
    97. dfs(vis[i],maxn);
    98. res=min(res,maxn-dist[vis[i+1]]);
    99. }
    100. printf("%lld\n",res);
    101. }
    102. int main() {
    103. // init();
    104. // stin();
    105. // ios::sync_with_stdio(false);
    106. scanf("%d",&T);
    107. // T=1;
    108. while(T--) hackT++,solve();
    109. return 0;
    110. }

  • 相关阅读:
    Nacos安装指南
    第七天项目实战一
    【TS】笔记-TypeScript环境搭建
    web 安全总结
    博客系统(ssm版本)
    Electron学习——解决npm install electron --save-dev出错/缓慢的问题
    王爽《汇编语言》检测点11.2详细解析
    bootstrap 主题
    STM32重要参考资料
    【JAVA基础】面向对象基础
  • 原文地址:https://blog.csdn.net/zzzyyzz_/article/details/133018303