不理解代码,需要有人讲解

img


该怎么理解画圈圈的那一行代码什么意思?主要是学的太勤了,不理解,特别是1.0和那个斜杆二

j=1.0/2就是1/2的意思
之所以1.0而不是1,是因为c++里除法如果都是整数会变成整除,结果是0,而不是0.5,所以要第一个数写成1.0

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7740171
  • 你也可以参考下这篇文章:离散数学实验三 实现整除关系这一偏序关系上所有盖住关系的求取,并判定对应偏序集是否为格
  • 除此之外, 这篇博客: 数据结构题目汇总中的 一个无向图  中包含  个点和  条边。矩阵  的第  行第  列元素  表示如果第  个点和第  个点没有联通的情况下,在这两个点之间构造一条边的代价。你的任务是在图中不断构造新的边使得整个图变成连通图,并且构造所消耗的代价最小。最终输出该代价和。 点的编号从1开始。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 第一行为一个数 ,表示图中点的个数。 

    而后的  行都由  个被空格分隔的数组成,第  行第  列表示第  个点和第  个点没有联通的情况下,在这两个点之间构造一条边的代价(即这  行  列为矩阵 )。 

    而后为一个数 ,表示图中已经存在的边的数量。 

    而后的  行都由两个被空格分隔的数组成,分别是已经存在的边相连接的两个点 和  。

    输出一个数,表示新增加的边的代价和。

    样例1

    input:

    4
    0 6692 8925 9679
    6692 0 9526 656
    8925 9526 0 2664
    9679 656 2664 0
    2
    1 3
    1 2

    output:

    656

    #include <iostream>
    using namespace std;
    int find(int* p, int key)
    {
     int index = key;
     while (p[index] != index)
     {
      index = p[index];
     }
     return index;
    }
    void allset(int* p, int n1, int n2)
    {
     int r1 = find(p, n1);
     int r2 = find(p, n2);
     if (r1 == r2)
      return;
     else
      p[r1] = r2;
     return;
    }
    void findmin(int** q, int n, int a[])
    {
     int min = q[0][0];
     for (int i = 0; i < n; i++)
     {
      for (int j = 0; j < n; j++)
      {
       if (q[i][j] < min)
       {
        min = q[i][j];
        a[0] = i+1;
        a[1] = j+1;
       }
      }
     }
     q[a[0] - 1][a[1] - 1] += 9999999;
    }
    int main()
    {
     int n;
     cin >> n;
     int* p = new int[n+1];
     p[0] = 0;
     for (int i = 1; i < n + 1; i++)
      p[i] = i;
     int** q = new int* [n];
     for (int i = 0; i < n; i++)
      q[i] = new int[n];
     for (int i = 0; i < n; i++)
     {
      for (int j = 0; j < n; j++)
      {
       cin >> q[i][j];
      }
     }
     int m;
     cin >> m;
     int k1,k2 ;
     for (int i = 0; i < m; i++)
     {
      cin >> k1 >> k2;
      allset(p, k1, k2);
      q[k1 - 1][k2-1] = 9999999;
     }
     for (int i = 0; i < n; i++)
      q[i][i] = 9999999;
     int k12[2];
     int sum = 0;
     while (m != n - 1)
     {
      findmin(q, n, k12);
      if(find(p,k12[0])==find(p,k12[1]))
      {
       ;
      }
      else 
      {
       allset(p, k12[0], k12[1]);
       m++;
       sum += q[k12[0] - 1][k12[1] - 1] - 9999999;
      }
     }
     cout <<sum;
     return 0;
    
    }

    17

    total submissions: 752times

    passed: 334times

    passing rate: 44.41%

    memory limit: 10485760(BYTE)

    time limit: 1000(MS)

    input limit: 1000(line)

    output limit: 1000(line)

    一个连通图中有  个点和  条边 (  > ) 。每条边都有对应的权值。题目需要你删除权值较大的边以消除多余的边,同时保证图的连通性。最终输出所有被删除的边的权值和。点的编号从1开始。

    第一行两个正整数  和 ,分别代表点的数量和边的数量。 

    之后  行每行有三个整数  分别表示边的两段端点序号和边的权值。

    输出一个正整数,代表所有被删除边的权值和。

    样例1

    input:

    5 5
    1 2 8
    1 3 1
    1 5 3
    2 4 5
    3 4 2

    output:

    8

    #include<iostream>
    using namespace std;
    int findmin(int**a,int m)
    {
        int k = a[0][2];
        int ki=0;
        for (int i = 0; i < m; i++)
        {
            if (a[i][2] < k)
            {
                k = a[i][2];
                ki = i;
            }
        }
        a[ki][2] += 1000;
        return ki;
    }
    int find(int* p, int key)
    {
        int index = key;
        while (p[index] != index)
        {
            index = p[index];
        }
        return index;
    }
    bool unionset(int* p, int n1, int n2)
    {
        int r1 = find(p, n1);
        int r2 = find(p, n2);
        if (r1 == r2)
            return false;
        else
        {
            p[r2] = p[r1];
        }
        return true;
    }
    int main()
    {
     int n, m;
     cin >> n >> m;
     int* p = new int[n+1];
        p[0] = 0;
        for (int i = 1; i < n+1; i++)
         {
            p[i] = i;
         }
        int** q = new int* [m];
        for (int i = 0; i < m; i++)
        {
            q[i] = new int[3];
        }
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                cin >> q[i][j];
            }
        }
        int tog = 0;
        for (int i = 0; i < m; i++)
        {
            int x = findmin(q, m);
            if (find(p, q[x][0]) == find(p, q[x][1]))
            {
                tog += q[x][2] - 1000;
            }
            else
            {
                unionset(p, q[x][0], q[x][1]);
            }
        }
        cout << tog;
        return 0;
    
    
    }

    18

    total submissions: 1193times

    passed: 353times

    passing rate: 29.59%

    memory limit: 10485760(BYTE)

    time limit: 1000(MS)

    input limit: 1000(line)

    output limit: 1000(line)

    一个有向图中有  个顶点和  条单向路径 , 请使用Dijkstra算法,求出某一个顶点到其他顶点的最短路径。

    第一行两个正整数  和 ,分别代表点的数量和路径的数量。   1< <20, 0<=  <50

    之后  行每行有三个整数  分别表示 路径 的起点、终点序号和路径长度。顶点编号从1开始,0<i,j<=n,0<k<100

    源点编号p ,0<p<=n

    Ⅰ.Dijkstra计算过程;

    Ⅱ.输出给定点v到其他各点的路径,以及最短距离。

    注意输出格式。橘色点代表空格。CRLF代表换行。

    按照Dijkstra算法获取最短路径顺序进行输出,如果没有路径则输出“No Path to ”【顶点编号,升序排列,中间使用空格隔开】

    样例1

    input:

    8 10
    1 6 10
    1 5 5
    6 3 1
    6 5 2
    3 4 4
    4 1 7
    4 3 6
    5 6 3
    5 3 9
    5 4 2
    1

    output:

    No.1 : 1 -> 5 , d = 5
    No.2 : 1 -> 5 -> 4 , d = 7
    No.3 : 1 -> 5 -> 6 , d = 8
    No.4 : 1 -> 5 -> 6 -> 3 , d = 9
    No.5 : No Path to 2 7 8

    #include<iostream>
    #include<stack>
    
    using namespace std;
    
    struct edge
    {
    	int bg, ed, val;
    	edge(int p = 0,int q = 0,int v = -1):bg(p), ed(q), val(v){}
    };
    
    struct Node
    {
    	int flag;//标示结点是否已被访问。 
    	Node(int f = 0):flag(f){}
    };
    //存储距离该结点最近的点以及路径长 
    struct path
    {
    	int length, k;
    	path(int l = 101,int kk = 0):length(l),k(kk){}
    	path(const path& p)
    	{
    		length = p.length;
    		k = p.k;
    	}
    };
    //得到距离该点最近的点的路径长度 
    int minpath(int bg, int ed, edge* e, int m)
    {
    	if(bg == ed)return 0;
    	int min = 101;
    	for(int i = 0;i < m; i++)
    		if(e[i].bg == bg && e[i].ed == ed && e[i].val < min)
    			min = e[i].val;
    
    		return min;
    }
    
    int main()
    {
    	int n, m, t1, t2, t3, s;
    	cin >> n >> m;
    	edge* e = new edge[m];
    	Node* N = new Node[n];
    	int* pre = new int[n];//与当前结点相连的前一个点。 
    	path* p = new path[n];
        
       
    	for(int i = 0; i < n; i++)
    		p[i].k = i;
    
    	for(int i = 0; i < n; i++)
    		pre[i] = -1;
    
    	for(int i = 0; i < m; i++)
    	{
    		cin >> t1 >> t2 >> t3;
    		e[i].bg = t1 - 1;
    		e[i].ed = t2 - 1;
    		e[i].val = t3;
    	}
    	cin >> s;
    	s -= 1;
    	pre[s] = s;
    	p[s].length = 0;
    	N[s].flag = 1;
    
    	int* key = new int[n];
    	for(int i = 0; i < n; i++)
    	{
    		p[i].length = minpath(s, i, e, m);
    		key[i] = p[i].length;//暂存各结点的最短路径。 
    	}
    
    	int c1, c2;
    	c1 = s;//从源点开始搜寻。 
    	for(int i = 0; i < n - 1; i++)
    	{
    		for(int j = 0; j < n; j++)
    		{
    			if(N[j].flag == 1)continue;//已访问,直接跳到下一个结点。 
    			if(key[j] > (key[c1] + minpath(c1, j, e, m)))
    				{
    					key[j] = key[c1] + minpath(c1, j, e, m);
    					pre[j] = c1;
    				}
    		}
    		int min = 101, j = 0;;
    		for(;j < n; j++)
    		{
    			if(N[j].flag == 1)continue;
    			if(key[j] <= min)
    				{
    					min = key[j];
    					c2 = j;
    				}
    		}
    		
    		N[c2].flag = 1;
    		if(i == 0)pre[c2] = c1;
    		p[c2].length = key[c2];
    		c1 = c2;
    	}
    
    	for(int i = 0; i < n; i++)
    		for(int j = i + 1; j < n; j++)
    			if(p[j].length < p[i].length)
    			{
    				path pp = p[j];
    				p[j] = p[i];
    				p[i]= pp;
    			}
    
    	int count = 1, flag = 0;
    	for(int i = 0; i < n; i++)
    	{
    		int num = p[i].k;
    		if(p[i].k == s)continue;
    		if(p[i].length == 101)
    		{
    			flag++;
    			continue;
    		}
    
    		stack<int> st;
    		st.push(num);
    		while(pre[num] != s)
    		{
    			st.push(pre[num]);
    			num = pre[num];
    		}
    
    		cout << "No." << count++ << " : " << s + 1 << " ";
    		while(!st.empty())
    		{
    			cout << "-> " << st.top() + 1 << " ";
    			st.pop();
    		}
    		cout << ", d = " << p[i].length << endl;
    	}
    
    	if(flag > 0)
    	{
    	cout << "No." << count << " : No Path to";
    	int *np = new int[flag];
    	int q = 0;
    	for(int i = 0; i < n; i++)
    	{
    		if(p[i].length == 101) np[q++] = p[i].k + 1;
    	}
    
    	for(int i = 0;i < flag; i++)
    		for(int j = i + 1; j < flag; j++)
    			if(np[j] < np[i])
    			{
    				int tmp = np[j];
    				np[j] = np[i];
    				np[i] = tmp;
    			}
    
    	for(int i = 0; i < flag; i++)cout << " " << np[i];
    	}
    
    	return 0;
    
    }
    
    

    19

    total submissions: 917times

    passed: 350times

    passing rate: 38.17%

    memory limit: 10485760(BYTE)

    time limit: 1000(MS)

    input limit: 1000(line)

    output limit: 1000(line)

    一个有向图中有  个顶点和  条单向路径 , 试求任意两地点间最短距离。

  • 您还可以看一下 纪佳琪老师的机器学习之线性回归理论与代码实践课程中的 数据归一化,画直线图,画损失函数图小节, 巩固相关知识点