http://www.lydsy.com/JudgeOnline/problem.php?id=3562
1 //Accepted 6020 kb 1012 ms 2 //由于题目的特殊要求:然而,令科学家们大为惊异的是,SHTSC 在变化过程中始终保持着一种特殊的性质: 3 //即不存在这样的原子序列 a1,a2,...,an(n>3)满足 a1 与 a2、a2 与 4 //a3、......、an-1 与 an 以及 an 与 a1 都通过化学键相连,但它们之间却没有其他化学键相连的情况。 5 //所以有如下结论: 6 //记所求答案为ans 7 //对于A x y,判断是否存在另外的一个点z使x,z有边,y,z有边 8 //如果存在z,则操作以后ans不变,否则ans+=1; 9 //对于D x y,判断是否存在另外的一个点z使x,z有边,y,z有边 10 //如果存在z,则操作以后ans不变,否则ans-=1; 11 #include <cstdio> 12 #include <cstring> 13 #include <iostream> 14 #include <queue> 15 #include <cmath> 16 #include <algorithm> 17 using namespace std; 18 #define ll long long 19 const int imax_n = 5005; 20 const int imax_m = 420005; 21 struct node 22 { 23 int v,u; 24 node() 25 { 26 27 } 28 node(int u,int v):u(u),v(v) 29 { 30 31 } 32 }p[imax_m]; 33 int head[imax_n],next[imax_m]; 34 int e; 35 int vis[imax_n]; 36 int ans; 37 int Q; 38 int n,m; 39 void init() 40 { 41 memset(head,-1,sizeof(head)); 42 memset(next,-1,sizeof(next)); 43 e=0; 44 } 45 void addEdge(int u,int v) 46 { 47 p[e]=node(u,v); 48 next[e]=head[u]; 49 head[u]=e++; 50 } 51 void deleteEdge(int u,int v) 52 { 53 int pre=-1,i; 54 for (i=head[u];i!=-1;i=next[i]) 55 { 56 if (p[i].v==v) break; 57 pre=i; 58 } 59 if (pre==-1) 60 { 61 //head[u]=next[next[i]]; 62 head[u]=next[i]; 63 } 64 else 65 { 66 //next[pre]=next[next[i]]; 67 next[pre]=next[i]; 68 } 69 } 70 void dfs(int u) 71 { 72 vis[u]=1; 73 for (int i=head[u];i!=-1;i=next[i]) 74 { 75 int v=p[i].v; 76 if (!vis[v]) 77 dfs(v); 78 } 79 } 80 int countTheNumberOfGraph() 81 { 82 memset(vis,0,sizeof(vis)); 83 int ans=0; 84 for (int i=1;i<=n;i++) 85 { 86 if (!vis[i]) 87 { 88 dfs(i); 89 ans++; 90 } 91 } 92 return ans; 93 } 94 /* 95 bool find(int x,int y) 96 { 97 int flag=0; 98 for (int i=1;i<=n;i++) 99 { 100 if (i==x) continue; 101 if (i==y) continue; 102 flag=0; 103 for (int j=head[i];j+1;j=next[j]) 104 { 105 if (p[j].v==x) flag++; 106 if (p[j].v==y) flag++; 107 if (flag==2) return 1; 108 } 109 } 110 return 0; 111 } 112 */ 113 int mark[imax_n]; 114 bool find(int x,int y) 115 { 116 memset(mark,0,sizeof(mark)); 117 for (int i=head[x];i+1;i=next[i]) 118 { 119 if (p[i].v!=y) 120 mark[p[i].v]++; 121 } 122 for (int i=head[y];i+1;i=next[i]) 123 { 124 if (p[i].v!=x) 125 mark[p[i].v]++; 126 } 127 for (int i=1;i<=n;i++) 128 { 129 //printf("mark[%d]=%d\n",i,mark[i]); 130 if (mark[i]==2) return 1; 131 } 132 return 0; 133 } 134 void operatorA(int x,int y) 135 { 136 if (find(x,y)==0) 137 { 138 //printf("A %d %d ans--\n",x,y); 139 ans--; 140 } 141 addEdge(x,y); 142 addEdge(y,x); 143 } 144 void operatorD(int x,int y) 145 { 146 if (find(x,y)==0) 147 { 148 //printf("D %d %d ans++\n",x,y); 149 ans++; 150 } 151 deleteEdge(x,y); 152 deleteEdge(y,x); 153 } 154 void operatorQ() 155 { 156 printf("%d\n",ans); 157 } 158 char s[5]; 159 int main() 160 { 161 //freopen("in.txt","r",stdin); 162 //freopen("out.txt","w",stdout); 163 while (scanf("%d%d",&n,&m)!=-1) 164 { 165 int x,y; 166 init(); 167 for (int i=0;i<m;i++) 168 { 169 scanf("%d%d",&x,&y); 170 addEdge(x,y); 171 addEdge(y,x); 172 } 173 ans=countTheNumberOfGraph(); 174 scanf("%d",&Q); 175 for (int i=0;i<Q;i++) 176 { 177 scanf("%s",s); 178 if (s[0]==‘A‘) 179 { 180 scanf("%d%d",&x,&y); 181 operatorA(x,y); 182 } 183 if (s[0]==‘D‘) 184 { 185 scanf("%d%d",&x,&y); 186 operatorD(x,y); 187 } 188 if (s[0]==‘Q‘) 189 { 190 operatorQ(); 191 } 192 } 193 } 194 return 0; 195 }
时间: 2024-10-10 23:41:56