2022-01-13每日刷题打卡

一、Y总视频进度

2022-01-13每日刷题打卡_第1张图片

二、刷题

2.1 AcWing 850. Dijkstra求最短路 II

1. 问题描述

2022-01-13每日刷题打卡_第2张图片

2. 问题解决

#include 
#include 
#include 
#include 

using namespace std;

typedef pair<int, int> PII;

const int N = 1e6 + 10;

int n, m;
int h[N], w[N], e[N], ne[N], idx;
int dist[N];
bool st[N];

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

int dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    heap.push({0, 1});

    while (heap.size())
    {
        auto t = heap.top();
        heap.pop();

        int ver = t.second, distance = t.first;

        if (st[ver]) continue;
        st[ver] = true;

        for (int i = h[ver]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (dist[j] > dist[ver] + w[i])
            {
                dist[j] = dist[ver] + w[i];
                heap.push({dist[j], j});
            }
        }
    }

    if (dist[n] == 0x3f3f3f3f) return -1;
    return dist[n];
}

int main()
{
    scanf("%d%d", &n, &m);

    memset(h, -1, sizeof h);
    while (m -- )
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c);
    }

    cout << dijkstra() << endl;

    return 0;
}

2.2 AcWing 853. 有边数限制的最短路

1. 问题描述

2022-01-13每日刷题打卡_第3张图片

2. 问题解决

#include 
#include 
#include 

using namespace std;

const int N = 510, M = 10010;

struct Edge
{
    int a, b, c;
}edges[M];

int n, m, k;
int dist[N];
int last[N];

void bellman_ford()
{
    memset(dist, 0x3f, sizeof(dist));
    
    dist[1] = 0;
    for(int i = 0; i < k; i++)
    {
        memcpy(last, dist, sizeof(dist));
        for(int j = 0; j < m; j++)
        {
            Edge e = edges[j];
            dist[e.b] = min(dist[e.b], last[e.a] + e.c);
        }
    }
}

int main()
{
    scanf("%d%d%d", &n, &m, &k);
    
    for(int i = 0; i < m; i++)
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        edges[i] = {a, b, c};
    }
    
    bellman_ford();
    
    if(dist[n] > 0x3f3f3f3f / 2) printf("impossible");
    else printf("%d\n", dist[n]);
    
    return 0;
}

2.3 蓝桥杯 十二届. 砝码称重

1. 问题描述

2022-01-13每日刷题打卡_第4张图片

2. 问题解决

#include 
using namespace std;
const long long inf = 0x7fffffffffffffff;
bool dp[106][100006];
int a[106];
int main()
{
    int i,j,n,sum = 0; cin>>n;
   for(i = 1;i <= n;i++){
      cin>>a[i];
      sum+= a[i];
   }

   for(i = 1;i <= n;i++){
       for(j = 1;j <= sum;j++){
           dp[i][j] = dp[i-1][j];
           if(!dp[i][j]){
               if(j == a[i]) dp[i][j] = 1; 
                //判定的值与当前选择的砝码相等
               if(dp[i-1][j + a[i]])  dp[i][j] = 1;
      			//检查当前i砝码与上一个状态(之前组合出的值)放在不同侧,是否可以组成j。
               if(dp[i-1][abs(j-a[i])]) dp[i][j] = 1;
      			//检查当前i砝码与上一个状态(之前组合出的值)放在同一侧,是否可以组成j。
           }
       }
   }

   long long ans = 0;
    for(j = 1;j <= sum;j++) if(dp[n][j]) ans++;
    cout<<ans;
    return 0;
}

你可能感兴趣的:(算法,c++)