Day 9.5

T1

可以证明每个点只会走一次

如果遇到环就在环的开始点打上标记

找到可行路的时候回溯,如果回溯时碰到有标记的点就输出Infinity!,否则直接输出ans就行

 1 #include <cstdio>
 2 int n,a[100010],b[100010],use[100010],in[100010],flag=0,incircle[100010];
 3 char ans[100010];
 4 int dfs(int x,int dep)
 5 {
 6     if (x<0||x>n-1) return 0;
 7     if (x==n-1){ans[dep]=‘\0‘;flag=1;return 1;}
 8     if (in[x]){incircle[x]=1;return 0;}
 9     if (use[x]) return 0;
10
11     use[x]=1;in[x]=1;
12     ans[dep]=‘a‘;
13     if (dfs(x+a[x],dep+1))
14     {
15         if (incircle[x]==1) flag=2;
16         return 1;
17     }
18     ans[dep]=‘b‘;
19     if (dfs(x+b[x],dep+1))
20     {
21         if (incircle[x]==1) flag=2;
22         return 1;
23     }
24     in[x]=0;
25     return 0;
26 }
27 int main()
28 {
29     scanf("%d",&n);
30     for (int i=0;i<n;i++) scanf("%d",&a[i]);
31     for (int i=0;i<n;i++) scanf("%d",&b[i]);
32     dfs(0,0);
33     if (flag==0) printf("No solution!");
34     if (flag==1) printf("%s",ans);
35     if (flag==2) printf("Infinity!");
36 }

T2

由于这是一个稀疏图,所以可以直接跑3000次SPFA

枚举公共路径的两个端点即可,但是要考虑直接走两条最短路更优的情况,所以要初始化答案为两条最短路的路径和

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 struct E{
 6     int next,to;
 7 }e[9000001];
 8 int n,m,a,b,sz=0,s1,t1,l1,s2,t2,l2,head[3001],x1,x2,f[3001][3001],que[3001],in[3001],top=-1,end=0,ans;
 9 void push(int x)
10 {
11     top++;
12     if (top==3001) top=0;
13     que[top]=x;
14 }
15 int pop()
16 {
17     int ans=que[end];
18     end++;
19     if (end==3001) end=0;
20     return ans;
21 }
22 bool empty()
23 {
24     return top+1==end;
25 }
26 void insert(int a,int b)
27 {
28     sz++;
29     e[sz].next=head[a];
30     head[a]=sz;
31     e[sz].to=b;
32 }
33 int spfa(int s)
34 {
35     push(s);f[s][s]=0;
36     while(!empty())
37     {
38         int x=pop();in[x]=0;
39         for (int i=head[x];i;i=e[i].next)
40         {
41             if (f[s][e[i].to]>f[s][x]+1)
42             {
43                 f[s][e[i].to]=f[s][x]+1;
44                 if (!in[e[i].to])
45                 {
46                     in[e[i].to]=1;
47                     push(e[i].to);
48                 }
49             }
50         }
51     }
52 }
53 int main()
54 {
55     scanf("%d%d",&n,&m);
56     for (int i=1;i<=m;i++)
57     {
58         scanf("%d%d",&a,&b);
59         insert(a,b);insert(b,a);
60     }
61     scanf("%d%d%d",&s1,&t1,&l1);
62     scanf("%d%d%d",&s2,&t2,&l2);
63     memset(f,0x7f,sizeof(f));
64     for (int i=1;i<=n;i++) spfa(i);
65     if (f[s1][t1]>l1||f[s2][t2]>l2)
66     {
67         printf("-1");
68         return 0;
69     }
70     ans=f[s1][t1]+f[s2][t2];
71     for (int i=1;i<=n;i++) for (int j=1;j<=n;j++)
72     {
73         ans=min(ans,f[s1][i]+f[s2][i]+f[i][j]+f[j][t1]+f[j][t2]);
74         ans=min(ans,f[s1][i]+f[s2][j]+f[i][j]+f[j][t1]+f[i][t2]);
75     }
76     printf("%d",m-ans);
77 }

T3

时间: 2024-10-12 19:36:57