首页 > 其他分享 >【数据结构OJ】实验10 拓扑排序与关键路径等

【数据结构OJ】实验10 拓扑排序与关键路径等

时间:2022-11-14 19:46:38浏览次数:52  
标签:10 cnt OJ idx int cin ++ front 数据结构

【数据结构OJ】实验10 拓扑排序与关键路径等

存一下代码:

A. 图综合练习--拓扑排序

整的很复杂

#include <iostream>

using namespace std;
const int N = 1005;
int n, d[N], top[N];
int q[N], v[N];
int h[N], e[N], ne[N], idx;

void add (int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void sort(int arr[], int len) {
    int i, j, temp;
    for (i = 0; i < len - 1; i++)
        for (j = 0; j < len - 1 - i; j++)
            if (arr[j] > arr[j + 1]) {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
}

void topsort(){
    int cnt = 0;
    int hh = 0, tt = -1;
    int t;
    for(int i = 1;i <= n; ++i)    if(d[i] == 0) q[++ tt] = i;
    while(hh <= tt){
        t = q[hh];
        top[cnt] = t;
        cnt ++;
        hh ++;
        int vi = 0;
        for(int i = h[t]; ~i; i = ne[i]){
            int j = e[i];
            d[j] --;
            if(d[j] == 0)   v[vi++] = j;
        }
        sort (v, vi);
        for (int i = 0; i < vi; i++)    q[++ tt] = v[i];//cout << v[i] << ' ';
    }
    for (int i = 0; i < cnt; i++)   cout << top[i] - 1 << ' ';
    cout << endl;
}


void solve () {
    cin >> n;
    for (int i = 0; i <= n * n; i++)    h[i] = -1, d[i] = 0;
       
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            int x;  cin >> x;
            if (x == 1) add (i, j), d[j] ++;
        }
    }
    topsort ();
}

int main () {
    int t;
    cin >> t;
    while (t --)    solve ();
}

B. 关键路径-STL版

#include <bits/stdc++.h>

using namespace std;
const int N = 105;
int m[N][N], n, e, x, y;
int a[N][N], ans1[N], ans2[N], ans[N];
bool vis[N];
queue<int> q;

void topsort () {
    int tmp = n;
    while (tmp --) {
        for (int i = 0; i < n; i++) {
            int din = 0;
            for (int j = 0; j < n; j++)    din += a[j][i];
            if (din == 0 && vis[i] == 0) {
                vis[i] = true;
                q.push(i);
                for (int k = 0; k < n; k++) {
                    if (a[i][k] > 0)    a[i][k]--;
                }
            }
        }
    }
}

int main() {
    cin >> n >> e;
    for (int i = 0; i < e; i++)     cin >> x >> y >> m[x][y];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (m[i][j] != 0)    a[i][j] = 1;
            else    a[i][j] = 0;
        }
    }

    topsort ();
    auto q1 = q;
    auto q2 = q1;

    ans1[q.front()] = 0;
    q.pop();
    while (!q.empty()) {
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            if (m[i][q.front()] > 0) {
                ans[cnt] = ans1[i] + m[i][q.front()];
                cnt++;
            }
        }
        ans1[q.front()] = *max_element (ans, ans + cnt);
        q.pop();
    }

    stack<int> nq1;
    while (!q1.empty()) {
        nq1.push(q1.front());
        q1.pop();
    }
    queue<int> nq;
    while (!nq1.empty()) {
        nq.push(nq1.top());
        nq1.pop();
    }

    //逆top
    ans2[nq.front()] = ans1[nq.front()];
    nq.pop();
    while (!nq.empty()) {
    
        int cnt = 0;
        for (int j = 0; j < n; j++) {
            if (m[nq.front()][j] > 0) {
                ans[cnt] = ans2[j] - m[nq.front()][j];
                cnt++;
            }
        }
        ans2[nq.front()] = *min_element (ans, ans + cnt);
        nq.pop();
    }

    for (int i = 0; i < n; i++)    cout << ans1[i] << " ";
    cout << endl;
    for (int i = 0; i < n; i++)    cout << ans2[i] << " ";
    cout << endl;;
}

C. 汉密尔顿回路

模拟走的过程

#include <bits/stdc++.h>

using namespace std;
const int N = 1005;
int n, m;
int e[N], ne[N], h[N], idx;
set <int> s[N];

void add (int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void solve () {
    int p;
    cin >> p;
    vector <int> v;
    set <int> ss;
    for (int i = 0; i < p; i++) {
        int x;  cin >> x;
        v.push_back (x);
        ss.insert (x);
    }
    if (p != n + 1 || v[0] != v[p-1] || ss.size () != n) {
        puts ("NO");
        return ;
    }
    for (int i = 0; i < v.size () - 1; i++) {
        int a = v[i], b = v[i + 1];
        if (s[a].count (b) == 0) {
            puts ("NO");
            return ;
        }
    }   
    puts ("YES");
}

int main () {
    //memset (h, -1, sizeof h);
    cin >> n >> m;
    for (int i = 0; i< m; i++) {
        int a, b;
        cin >> a >> b;
        //add (a, b), add (b, a);
        s[a].insert (b), s[b].insert (a);
    }
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}

D. 六度空间

因为数据水,floyd就过了

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;
const int N = 1005, INF = 1e9;
int dis[N][N];
int h[N], e[N], ne[N], idx;

int main () {
    ios::sync_with_stdio (0);cin.tie (0);cout.tie (0);
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) {
        for (int j = 1; j <= n; j ++) {
            if (i == j) dis[i][j] = 0;
            else dis[i][j] = INF;
        }
    }

    while (m --) {
        int a, b;
        cin >> a >> b;
        dis[a][b] = dis[b][a] = 1;
    }

    for (int k = 1; k <= n; k ++)
        for (int i = 1; i <= n; i ++)
            for (int j = 1; j <= n; j ++)
                dis[i][j] = min (dis[i][j], dis[i][k]+ dis[k][j]);


    for (int i = 1; i <= n; i++) {
        cout << i << ": ";
        int cnt = 0;
        for (int j = 1; j <= n; j++) {
            if (dis[i][j] <= 6) cnt ++;
        }
        double xx = 100.0 * cnt / n;
        cout << fixed << setprecision (2) << xx << "%\n";
    }
}


//也就是求到该点距离<=6的点的个数(含自身)
//直接n遍dijkstra

E. 货币套汇(图路径)

#include <bits/stdc++.h>

using namespace std;
const int N = 35, inf = 1e9;
int n, m;
map <string, int> mp;
bool vis[N];
int cnt[N];
int h[N], e[N], ne[N], idx;
double w[N], dis[N];

void add (int a, int b, double c) {
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}

bool spfa () {
    queue <int> q;
    vis[1] = true;
    cnt[1] = 1;
    dis[1] = 1;
    q.push(1);
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        vis[u] = false;
        for (int i = h[u]; i != -1; i = ne[i]) {
			int v = e[i];
            double ww = dis[u] * w[i];
            if(dis[v] < ww) {
                dis[v] = ww;
                if(!vis[v]) {
                    vis[v] = false;
                    cnt[v] ++;
                    if(cnt[v] > n)  return true;
                    q.push(v);
                }
            }
        }
    }
    return false;
}

void solve () {
    memset (h, -1, sizeof h), idx = 0;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        string s;
        cin >> s;
        mp[s] = i;
    }
    while (m --) {
        string x, y;
        double c;
        cin >> x >> c >> y;
        int a = mp[x], b = mp[y];
        add (a, b, c);
    }
    if (spfa ())    puts ("YES");
    else    puts ("NO");
}

int main () {
    int t;
    cin >> t;
    while (t --)    solve ();
}

//判正环

F. 拯救007

如代码:

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N = 105, INF = 1e9;
int n, m;
int X[N], Y[N], a[N][N];
int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

bool Range (int x, int y) {
    if (x > -50 && x < 50 && y > -50 && y < 50)     return true;
    return false;
}

bool check_in (int x, int y) { //check能否从圆内跳到(x,y)
    //cout << x << ' ' << y << endl;
    if (x * x + y * y <= (m + 7.5) * (m + 7.5))     return true;
    return false;
} 

bool check_out (int x, int y) { //check能否从(x,y)跳出框
    //cout << x << ' ' << y << endl;
    for (int i = 0; i < 4; i++) {
        int xx = x + dx[i] * m, yy = y + dy[i] * m;
        //cout << xx << ' ' << yy << endl;
        if (!Range (xx, yy))    return true;
    }
    return false;
} 

bool check (int xa, int ya, int xb, int yb) { //check(xa, ya)与(xb, yb)能否直接可达
    if ((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb) <= m * m) return true;
    return false;
} 

void print () {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cout << a[i][j] << ' ';
        }
        cout << endl;
    }
}

signed main () {
    cin >> n >> m;
    for (int i = 0; i < n; i++)    cin >> X[i] >> Y[i];
    vector <int> st; //可达起点的点
    for (int i = 0; i < n; i++) {
        if (check_in (X[i], Y[i]))  st.push_back (i);
    }
    vector <int> ed; //可跳出去的点
    for (int i = 0; i < n; i++) {
        if (check_out (X[i], Y[i]))  ed.push_back (i);
    }

    // for (int i = 0; i < n; i ++ )
    //     for (int j = 0; j < n; j ++ )
    //         if (i == j) a[i][j] = 0;
    //         else a[i][j] = INF;

    //处理任意可达的两点
    for (int i = 0; i < n; i++) {
        a[i][i] = 1;
        for (int j = i + 1; j < n; j++) {
            if (check (X[i], Y[i], X[j], Y[j])) a[i][j] = a[j][i] = 1;
        }
    }
    //print ();

    for (int k = 0; k < n; k ++)
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < n; j ++) {
                if (a[i][k] && a[k][j]) a[i][j] = 1;
            }
                //a[i][j] = min (a[i][j], a[i][k]+ a[k][j]);

    //print ();

    for (auto i : st) {
        for (auto j : ed) {
            //cout << i << ' ' << j << endl;
            if (a[i][j]) {
                puts ("Yes");
                return 0;
            }
        }
    }
    puts ("No");
}

G. 先序+中序还原二叉树

dfs

#include <bits/stdc++.h>
using namespace std;

int dfs(char *pre, char *in, int n) {
    if (n == 0)    return 0;
    int i;
    for (i = 0; i < n; i++) {
        if (in[i] == pre[0])    break;
    }
    int left = dfs(pre + 1, in, i);                     
    int right = dfs(pre + i + 1, in + i + 1, n - i - 1); 
    return max(left, right) + 1; 
}
int main() {
    int n;
    cin >> n;
    char pre[n + 1], in[n + 1]; //先序和中序
    cin >> pre >> in;
    cout << dfs(pre, in, n) << endl;
}

标签:10,cnt,OJ,idx,int,cin,++,front,数据结构
From: https://www.cnblogs.com/CTing/p/16890117.html

相关文章