第一题的剪枝真的没有想到。
1 #include<cstring> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstdio> 6 7 using namespace std; 8 inline int read() 9 { 10 int x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 16 int n; 17 int a[27]; 18 19 int check() 20 { 21 int res=0; 22 for (int i=2;i<=n;i++) 23 if (abs(a[i]-a[i-1])>1) res++; 24 return res; 25 } 26 bool dfs(int dep,int last) 27 { 28 if (dep==0) 29 { 30 bool flag=1; 31 for (int i=1;i<=n;i++) 32 if (a[i]!=i){flag=0;break;} 33 if (flag) return 1; 34 else return 0; 35 } 36 if (dep-check()<0)return 0; 37 for (int i=2;i<=n;i++) 38 { 39 if (i==last)continue; 40 for (int j=1;(j<<1)<=i;j++) swap(a[j],a[i-j+1]); 41 if (dfs(dep-1,i)) return 1; 42 for (int j=1;(j<<1)<=i;j++) swap(a[j],a[i-j+1]); 43 } 44 return 0; 45 } 46 int main() 47 { 48 int T=read(); 49 while(T--) 50 { 51 n=read(); 52 for (int i=1;i<=n;i++) 53 a[i]=read(); 54 int static up=(n-1)*2; 55 for (int i=0;i<=up;i++) 56 if (dfs(i,n+1)) 57 { 58 printf("%d\n",i); 59 break; 60 } 61 } 62 }
第二题开始题目没看懂,以为炸了以后会断开,结果
居然是不断开的,那么真的无语了,然后就是缩点后找最长路,
带权值的。
O(n)
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 7 #define N 1000007 8 using namespace std; 9 inline int read() 10 { 11 int x=0;char ch=getchar(); 12 while(ch<'0'||ch>'9')ch=getchar(); 13 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 14 return x; 15 } 16 17 int n,m,f[N]; 18 int Time=0,top=0,scc=0,ans; 19 int dfn[N],low[N],instack[N],q[N],belong[N],chu[N]; 20 int cnt,head[N],next[N],rea[N],skt[N]; 21 int cnt_new,hed_new[N],nxt_new[N],rea_new[N]; 22 bool flag[N]; 23 24 void add(int u,int v) 25 { 26 cnt++; 27 next[cnt]=head[u]; 28 head[u]=cnt; 29 rea[cnt]=v; 30 } 31 void tarjan(int u) 32 { 33 low[u]=dfn[u]=++Time; 34 q[++top]=u,instack[u]=1; 35 for (int i=head[u];i!=-1;i=next[i]) 36 { 37 int v=rea[i]; 38 if (dfn[v]==0) 39 { 40 tarjan(v); 41 low[u]=min(low[v],low[u]); 42 } 43 else if (instack[v]) low[u]=min(low[u],dfn[v]); 44 } 45 if (low[u]==dfn[u]) 46 { 47 scc++; 48 int x=-1; 49 while (x!=u) 50 { 51 x=q[top--]; 52 instack[x]=0; 53 belong[x]=scc; 54 ++skt[scc]; 55 } 56 } 57 } 58 void add_new(int u,int v) 59 { 60 nxt_new[++cnt_new]=hed_new[u]; 61 hed_new[u]=cnt_new; 62 rea_new[cnt_new]=v; 63 } 64 void rebuild() 65 { 66 for (int u=1;u<=n;u++) 67 { 68 for (int i=head[u];i!=-1;i=next[i]) 69 { 70 int v=rea[i]; 71 if (belong[u]!=belong[v]) add_new(belong[u],belong[v]),flag[belong[v]]=1; 72 } 73 } 74 } 75 void dfs(int u) 76 { 77 if (f[u]!=-1) return; 78 int res=0; 79 for (int i=hed_new[u];i!=-1;i=nxt_new[i]) 80 { 81 int v=rea_new[i]; 82 dfs(v); 83 res=max(res,f[v]); 84 } 85 f[u]=skt[u]+res; 86 } 87 int main() 88 { 89 freopen("bomb.in","r",stdin); 90 freopen("bomb.out","w",stdout); 91 92 n=read(),m=read(); 93 memset(head,-1,sizeof(head)); 94 memset(hed_new,-1,sizeof(hed_new)); 95 for (int i=1;i<=m;i++) 96 { 97 int x=read(),y=read(); 98 add(x,y); 99 } 100 for (int i=1;i<=n;i++) 101 if (dfn[i]==0) tarjan(i); 102 rebuild(); 103 memset(f,-1,sizeof(f)); 104 for (int i=1;i<=scc;i++) 105 if (!flag[i])dfs(i); 106 int ans=0; 107 for (int i=1;i<=scc;i++) 108 ans=max(ans,f[i]); 109 printf("%d\n",ans); 110 }
第三题还不会。