7.9总结

本周完成了数据结构小学期第一阶段的任务pta的题目部分

遇到的问题:kmp算法不懂 关键路径拓扑排序有问题

关键路径 

编写程序求出工程的所有关键活动,并计算完成工程所需的最短时间。

#include<iostream>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
#define maxx 200
#define INF 10000
int edges[maxx][maxx];
int in[maxx] = { 0 };
int out[maxx] = { 0 };
int early[maxx] = { 0 };
int late[maxx];
int max1[1]={0};
int s[maxx]={0};
int ne, nv;
int l=0;
int temp1=0;
int earlytime()
{
int cnt = 0;
queue<int>qu;
for (int i = 1; i <= nv; i++)
{
if (in[i] == 0)
qu.push(i);//找到入度为零的节点,就是起点
}
while (!qu.empty())
{
int temp = qu.front();
cnt++;
qu.pop();
for (int i = 1; i <= nv; i++)
{
if (edges[temp][i] != INF)
{
in[i]--;

early[i] = max(early[i], early[temp] + edges[temp][i]);
if (in[i] == 0)qu.push(i);
}

}

}
if (cnt != nv)
return -1;//无法完成任务
else
{
int amount = -999;
for (int i = 1; i <= nv; i++)
{
if (early[i] > amount)
amount = early[i];
}
return amount;//找出最后的最大值
}


}

void latetime(int count)
{
queue<int>qu;
for (int i = 1; i <= nv; i++)
{
if (out[i] == 0)
{
qu.push(i);
late[i] = count;
}
}
while (!qu.empty())
{
int temp = qu.front();
qu.pop();
for (int i = nv; i >=1; i--)//反着来
{
if (edges[i][temp] != INF)//edges[i][temp] 
{
out[i]--;
late[i] = min(late[i], late[temp] - edges[i][temp]);

if (out[i] == 0)
qu.push(i);
}
}
}




}

int main()
{
int n, m;
while(cin >> n >> m){
     nv = n;
     ne = m;
     memset(in,0,sizeof in);
     memset(out,0,sizeof out);
     memset(early,0,sizeof early);
     memset(late,0,sizeof late);
     memset(s,0,sizeof s);
     
     for (int i = 0; i < maxx; i++)
     {
     late[i] = INF;
     for (int j = 0; j < maxx; j++)
     {
     edges[i][j] = INF;
     
     }
     }
    
     for (int i = 1; i <= ne; i++)
     {
     int a, b, c;
     cin >> a >> b >> c;
     edges[a][b] = c;
     in[b]++;
     out[a]++;
     }
     int count = earlytime();
     if (count == -1)
     {
     cout << "unworkable project"<<endl;
     continue;
     }
     latetime(count);
     cout << count << endl;
     for (int i = 1; i <= nv; i++)//从小到大保证任务开始的交接点编号小者优先
     {
     for (int j = nv; j >= 1; j--)//从大到小保证起点编号相同时,与输入时任务的顺序相反。
     {
     if (edges[i][j] != INF&&late[j] - early[i]==edges[i][j])
     { s[2*l]=i;
                    s[2*l+1]=j;
                    ++l;
     
                    max1[0]++;
                    
     }
    
     }
     }
      
      for(int k =0;k<max1[0];k++){
          if(s[2*k]==s[2*k+2]){
              if(s[2*k+1]>s[2*k+3]){
                  temp1=s[2*k+1];
                  s[2*k+1]=s[2*k+3];
                  s[2*k+3]=temp1;
              }
          }
          
         
      }
         for(int k=0;k<max1[0];k++){
              cout<<s[2*k]<<"->"<<s[2*k+1]<<endl;
          }
}
}

 jmu-ds-实现KMP 

给两个字符串A、B, 从A中找出第一次出现B的位置。

#include<stdio.h>
#include<string.h>
const int MAX=1000;

void getnext(char str[],int len,int next[])// 递推计算Next数组,模板串为str,模板串长度为len
{
    int i=0,j=0;
    next[0]=-1;
    for(i=1;i<len;i++)
    {
        while(j>0&&str[i]!=str[j])
            j=next[j-1];
        if(str[i]==str[j])
            j++;
        next[i]=j;
    }
}
 int findt(char s[],int lens,char t[],int lent,int next[])// 在字符串s中匹配字符串t,s长度为lens,t长度为lent,t的Next数组为next[],返回t第一次出现的位置
 {
    int i=0,j=0;
    while(i<lens&&j<lent)
    {
        if(j==-1 || s[i]==t[j])
        {
            j++;
            i++;
        }
        else
        {
            j=next[j];
        }
    }
    if(j==lent)
        return i-j;
    else
        return -1;
 }

 int main()
 {
    int n,a;
    char s[MAX],t[MAX];
    int next[MAX];
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s %s",s,t);
        int lens = strlen(s);
        int lent = strlen(t);
        getnext(t,lent,next);
        a=findt(s,lens,t,lent,next);
        if(a==-1)
            printf("not find!\n");
        else
            printf("%d\n",a);
    }
 }

 

posted @ 2022-07-09 21:01  慢漫曼蔓  阅读(18)  评论(0)    收藏  举报