首页 > 其他分享 >洛谷 P3530 / bzoj2788【tarjan】【差分约束】

洛谷 P3530 / bzoj2788【tarjan】【差分约束】

时间:2022-10-10 17:36:19浏览次数:50  
标签:P3530 tarjan 洛谷 min int dfn mp now low

判断是否有解可以使用差分约束。

求解赛车手的成绩的取值可以使用 Floyd。但是 \(O(n^3)\) 会 TLE。

可以先进行一次缩点。

然后进行 Floyd 求出每一个连通块内的最长路径 \(long_i\),然后最终答案是 \(\sum_{\\i=1}^{cnt} long_i\)。

存在负环就是无解。这道题无法使用 SPFA。

#include <bits/stdc++.h>

using namespace std;

/* ovo */
const int o = 0, _ = 0;
/* ovo */

const int N = 3333;
int mp[N][N];
vector <int> z[N], scc[N];
int longer[N];
int dfn[N], low[N], belong[N], counting, total, n, m1, m2;
stack <int> stk;
bool instk[N];

void doing()
{
  int p = stk.top();
  stk.pop();
  instk[p] = false;
  scc[total].push_back(p);
  belong[p] = total;
}

void dfs(int now)
{
  dfn[now] = low[now] = ++ counting;
  stk.push(now);
  instk[now] = true;
  for (auto &p : z[now])
    if (!dfn[p])
    {
      dfs(p);
      low[now] = min(low[p], low[now]);
    }
    else if (instk[p])
      low[now] = min(low[now], dfn[p]);
  if (dfn[now] == low[now])
  {
    total ++;
    while (stk.top() != now)
      doing();
    doing();
  }
}

void tarjan()
{
  for (int i = 1; i <= n; i ++)
    if (!dfn[i])
      dfs(i);
}

signed main()
{
  cin >> n >> m1 >> m2;
  memset (mp, 0x3f, sizeof mp);
  for (int i = 1; i <= n; i ++)
    mp[i][i] = 0;
  while (m1 --)
  {
    int a, b;
    cin >> a >> b;
    z[a].push_back(b);
    z[b].push_back(a);
    mp[a][b] = min(mp[a][b], -1);
    mp[b][a] = min(mp[b][a], 1);
  }
  while (m2 --)
  {
    int a, b;
    cin >> a >> b;
    z[a].push_back(b);
    mp[a][b] = min(mp[a][b], 0);
  }
  tarjan();
  for (int k = 1; k <= n; k ++)
    for (int i = 1; i <= n; i ++)
      if (belong[i] == belong[k])
        for (int j = 1; j <= n; j ++)
          if (belong[i] == belong[j])
            mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]);
  for (int i = 1; i <= n; i ++)
    if (mp[i][i])
    {
      cout << "NIE\n";
      return 0;
    }
  for (int i = 1; i <= n; i ++)
    for (int j = 1; j <= n; j ++)
      if (belong[i] == belong[j])
        longer[belong[i]] = max(longer[belong[i]], mp[i][j]);
  long long result = 0;
  for (int i = 1; i <= total; i ++)
    result += longer[i] + 1;
  cout << result << '\n';
  return o^_^o;
}

标签:P3530,tarjan,洛谷,min,int,dfn,mp,now,low
From: https://www.cnblogs.com/lxylluvio/p/luogu3530bzoj2788.html

相关文章

  • 洛谷 P5194 [USACO05DEC]Scales S 折半搜索
    题目https://www.luogu.com.cn/problem/P5194思路\(n\leq1000\)的范围很吓人,但是按照【每个砝码的质量至少等于前面两个砝码的质量的和】的规则,打表可知n在50时总重量......
  • 【做题笔记】洛谷P5584 【SWTR-01】Sunny's Crystals
    ProblemP5584【SWTR-01】Sunny'sCrystals题目大意:给你一个长度为\(n\)的序列,每次可以删掉下标为\(2\)的非负整数次幂的数,删掉一个数后他后面的数会往前补,问删掉所......
  • 洛谷 P6146
    由于博主是只鸽子,所以咕咕咕。()不,应该是目录不在更新,请关注博客首页。有空我把目录更新一下,好久不更了传送门YouareMiserable(ATLv.15)思路Stage1这题其实是个......
  • Solution -「CSTC 2017」「洛谷 P3772」游戏
    \(\mathscr{Description}\)  有\(n\)个随机真值\(x_{1..n}\),已知\(P(x_1=1)=p_1\),对于\(2\lei\len\),\(P(x_i=1\midx_{i-1}=1)=p_i\),\(P(x_i=1\midx_{i......
  • 洛谷 P2387 [NOI2014] 魔法森林 题解【动态加点 SPFA】
    题目大意给定一个由\(n\)个点\(m\)条边的无向图,每条边有权值\((a,b)\),求一条路径使这条路径上的\((a_{\max}+b_{\max})\)最小。思路正解应该是LCT动态维护MST......
  • Solution -「SDOI 2017」「洛谷 P3706」硬币游戏
    \(\mathscr{Description}\)  Link.  给定\(n\)个长度为\(m\)且两两不同的字符串\(S_{1..n}\),字符集\(|\Sigma|=2\).各位置独立在\(\Sigma\)中均匀随机,......
  • P5730 【深基5.例10】显示屏 洛谷
    #include<stdio.h>intmain(){charstr1[30]="XXX..XXXXXXXX.XXXXXXXXXXXXXXXX";charstr2[30]="X.X..X..X..XX.XX..X....XX.XX.X";charstr3[30]="X.......
  • 网络流24题 -洛谷 P2762 太空飞行计划问题
    P2762太空飞行计划问题题意给你n个实验m个仪器(原题中n和m反了一下)第i个实验会给一个赞助费\(c[i]\)每个实验都有相应的实验仪器买第m个实验器材要\(c_2[i]\)的钱问......
  • 【复习笔记】tarjan算法
    写点东西好复习,主要是tarjan这个东西学了容易忘,忘了也不难捡起来,但捡起来了又容易忘。tarjan的前置知识dfs树就暂且咕咕了,因为这东西没什么模板,变化挺多的,估计是写不完。......
  • 洛谷——P1071 [NOIP2009 提高组] 潜伏者
    本次博客,我将记录洛谷P1071潜伏者[NOIP2009提高组]潜伏者理解题意:对于failed的情况,有以下三种:1.扫描完毕后发现某个字母没有对应的翻译2.扫描过程中发现自相矛盾,这......