2024.1.25 寒假训练记录(8)

禁止摸鱼!!!!!!

目前计划是根据网上那个广为流传的xcpc算法清单补一下图论和数据结构的算法

在准备27号的训练赛,这两天博客只放洛谷的题目

文章目录

  • 洛谷 P1113 杂务
  • 洛谷 P1983 [NOIP2013 普及组] 车站分级
  • 洛谷 P1038 [NOIP2003 提高组] 神经网络

洛谷 P1113 杂务

题目链接

拓扑排序的板题,有段时间没做拓扑,需要注意的点是,结束点并不是出度为0的点,因为出度为0的点可能有很多,要遍历所有结点的完成时间取最大的才是结束点

#include 

using namespace std;

#define int long long
#define INF 0x3f3f3f3f

typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;

const int N = 11;

void solve()
{
	int n;
    cin >> n;
    vector<int> w(n + 1), ind(n + 1), oud(n + 1);
    vector<vector<int>> g(n + 1);
    for (int i = 0; i < n; i ++ )
    {
        int id, x;
        cin >> id >> w[id] >> x;
        while (x != 0)
        {
            g[x].push_back(id);
            oud[x] ++ ;
            ind[id] ++ ;
            cin >> x;
        }
    }
    queue<int> q;
    vector<int> et(n + 1);
    for (int i = 1; i <= n; i ++ )
        if (ind[i] == 0)
        {
            et[i] = w[i];
            q.push(i);
        }
    while (q.size())
    {
        auto t = q.front();
        q.pop();

        for (int i = 0; i < g[t].size(); i ++ )
        {
            int j = g[t][i];
            et[j] = max(et[j], et[t] + w[j]);
            ind[j] -- ;
            if (ind[j] == 0) q.push(j);
        }
    }

    int ans = 0;
    for (int i = 1; i <= n; i ++ ) ans = max(ans, et[i]);
    cout << ans << '\n';
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);

	int t = 1;
	// cin >> t;
	while (t -- )
	{
		solve();
	}
}

洛谷 P1983 [NOIP2013 普及组] 车站分级

题目链接

因为数据比较小所以可以单独建个二维数组的图,不然会tle或者mle

#include 

using namespace std;

// #define int long long
#define INF 0x3f3f3f3f

typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;

const int N = 1010;

bool edge[N][N];

void solve()
{
	int n, m;
    cin >> n >> m;
    vector<vector<int>> g(n + 1);
    vector<int> ind(n + 1);
    for (int i = 0; i < m; i ++ )
    {
        int num; cin >> num;
        vector<bool> st(n + 1);
        vector<int> stop;
        for (int j = 0; j < num; j ++ )
        {
            int x; cin >> x;
            stop.push_back(x);
            st[x] = true;
        }
        for (int j = stop[0]; j <= stop[stop.size() - 1]; j ++ )
        {
            if (!st[j])
            {
                for (auto t : stop)
                {
                    if (edge[j][t]) continue;
                    g[j].push_back(t);
                    edge[j][t] = true;
                    ind[t] ++ ;
                }
            }
        }
    }
    queue<int> q;
    vector<int> dist(n + 1);
    for (int i = 1; i <= n; i ++ )
    {
        if (ind[i] == 0)
        {
            q.push(i);
            dist[i] = 1;
        }
    }
    while (q.size())
    {
        auto t = q.front();
        q.pop();

        for (int i = 0; i < g[t].size(); i ++ )
        {
            int j = g[t][i];
            dist[j] = max(dist[j], dist[t] + 1);
            ind[j] -- ;
            if (ind[j] == 0) q.push(j);
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; i ++ ) ans = max(ans, dist[i]);
    cout << ans << '\n';
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);

	int t = 1;
	// cin >> t;
	while (t -- )
	{
		solve();
	}
}

洛谷 P1038 [NOIP2003 提高组] 神经网络

题目链接

这题注意的坑点是,每秒活跃的结点都会传出信息,不是当前结点前面的结点都传递了之后当前结点再传递信息

#include 

using namespace std;

// #define int long long
#define INF 0x3f3f3f3f

typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;

const int N = 1010;

void solve()
{
	int n, m;
    cin >> n >> m;
    vector<int> ind(n + 1), oud(n + 1);
    vector<vector<PII>> g(n + 1);
    queue<int> q;
    vector<int> u(n + 1);
    vector<int> c(n + 1);
    vector<bool> st(n + 1);

    for (int i = 0; i < n; i ++ )
    {
        cin >> c[i + 1] >> u[i + 1];
        if (c[i + 1] >= 1) q.push(i + 1), st[i + 1] = true;
        else c[i + 1] -= u[i + 1];
    }
    for (int i = 0; i < m; i ++ )
    {
        int a, b, x;
        cin >> a >> b >> x;
        g[a].push_back(make_pair(b, x));
        ind[b] ++ ;
        oud[a] ++ ;
    }

    while (q.size())
    {
        auto t = q.front();
        q.pop();
        st[t] = false;
        if (c[t] <= 0) continue;
        for (int i = 0; i < g[t].size(); i ++ )
        {
            int j = g[t][i].first;
            c[j] += g[t][i].second * c[t];
            ind[j] -- ;
            if (c[j] > 0 && st[j] == false)
            {
                // c[j] -= u[j];
                st[j] = true;
                q.push(j);
            }
        }
    }

    bool flag = false;
    for (int i = 1; i <= n; i ++ )
    {
        if (c[i] > 0 && oud[i] == 0)
        {
            flag = true;
            cout << i << ' ' << c[i] << '\n';
        }
    }
    if (!flag) cout << "NULL\n";
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);

	int t = 1;
	// cin >> t;
	while (t -- )
	{
		solve();
	}
}

你可能感兴趣的:(2024寒假训练记录,算法)