图论测试 2017.1.17
因为只用两种颜色,所以相邻的省市的颜色一定相反,然后dfs/bfs就可以了。注意图可能不会联通。
Code
1 #include<iostream> 2 #include<fstream> 3 #include<sstream> 4 #include<cstdio> 5 #include<cstdlib> 6 #include<cstring> 7 #include<ctime> 8 #include<cctype> 9 #include<cmath> 10 #include<algorithm> 11 #include<stack> 12 #include<queue> 13 #include<set> 14 #include<map> 15 #include<vector> 16 using namespace std; 17 typedef bool boolean; 18 #define smin(a, b) (a) = min((a), (b)) 19 #define smax(as, b) (a) = max((a), (b)) 20 template<typename T> 21 inline boolean readInteger(T& u){ 22 char x; 23 int aFlag = 1; 24 while(!isdigit((x = getchar())) && x != '-' && x != -1); 25 if(x == -1) return false; 26 if(x == '-'){ 27 x = getchar(); 28 aFlag = -1; 29 } 30 for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0'); 31 ungetc(x, stdin); 32 u *= aFlag; 33 return true; 34 } 35 36 typedef class Edge{ 37 public: 38 int end; 39 int next; 40 Edge(const int end = 0, const int next = 0):end(end), next(next){ } 41 }Edge; 42 43 typedef class MapManager{ 44 public: 45 int ce; 46 Edge* edges; 47 int* h; 48 MapManager():ce(0), edges(NULL), h(NULL){ } 49 MapManager(int points, int limit):ce(0){ 50 h = new int[(const int)(points + 1)]; 51 edges = new Edge[(const int)(limit + 1)]; 52 memset(h, 0, sizeof(int) * (points + 1)); 53 } 54 inline void addEdge(int from, int end){ 55 edges[++ce] = Edge(end, h[from]); 56 h[from] = ce; 57 } 58 inline void addDoubleEdge(int from, int end){ 59 addEdge(from, end); 60 addEdge(end, from); 61 } 62 inline void clear(){ 63 delete[] edges; 64 delete[] h; 65 ce = 0; 66 } 67 Edge& operator [](int pos){ 68 return edges[pos]; 69 } 70 }MapManager; 71 72 #define m_begin(g, i) (g).h[(i)] 73 74 int T; 75 int n, m; 76 MapManager g; 77 78 inline void init(){ 79 readInteger(n); 80 readInteger(m); 81 g = MapManager(n, 2 * m); 82 for(int i = 1, a, b; i <= m; i++){ 83 readInteger(a); 84 readInteger(b); 85 g.addDoubleEdge(a, b); 86 } 87 } 88 89 boolean* visited; 90 int* colors; 91 queue<int> que; 92 93 inline boolean check(int s){ 94 while(!que.empty()) que.pop(); 95 que.push(s); 96 visited[s] = true; 97 colors[s] = 0; 98 while(!que.empty()){ 99 int e = que.front(); 100 que.pop(); 101 for(int i = m_begin(g, e); i != 0; i = g[i].next){ 102 int& eu = g[i].end; 103 if(!visited[eu]){ 104 visited[eu] = true; 105 colors[eu] = colors[e] ^ 1; 106 que.push(eu); 107 }else if(colors[eu] == colors[e]) return false; 108 } 109 } 110 return true; 111 } 112 113 inline boolean solve(){ 114 visited = new boolean[(const int)(n + 1)]; 115 colors = new int[(const int)(n + 1)]; 116 memset(visited, false, sizeof(boolean) * (n + 1)); 117 for(int i = 1; i <= n; i++) 118 if(!visited[i] && !check(i)) 119 return false; 120 return true; 121 } 122 123 inline void clear(){ 124 delete[] visited; 125 delete[] colors; 126 g.clear(); 127 } 128 129 int main(){ 130 freopen("color.in", "r", stdin); 131 freopen("color.out", "w", stdout); 132 readInteger(T); 133 while(T--){ 134 init(); 135 boolean res = solve(); 136 printf("%s\n", (res) ? ("YES") : ("NO")); 137 clear(); 138 } 139 return 0; 140 }
随便跑一遍最短路,注意加上抄书的时间。(包括结束的点)
Code
1 #include<iostream> 2 #include<fstream> 3 #include<sstream> 4 #include<cstdio> 5 #include<cstdlib> 6 #include<cstring> 7 #include<ctime> 8 #include<cctype> 9 #include<cmath> 10 #include<algorithm> 11 #include<stack> 12 #include<queue> 13 #include<set> 14 #include<map> 15 #include<vector> 16 using namespace std; 17 typedef bool boolean; 18 #define smin(a, b) (a) = min((a), (b)) 19 #define smax(a, b) (a) = max((a), (b)) 20 template<typename T> 21 inline boolean readInteger(T& u){ 22 char x; 23 int aFlag = 1; 24 while(!isdigit((x = getchar())) && x != '-' && x != -1); 25 if(x == -1) return false; 26 if(x == '-'){ 27 x = getchar(); 28 aFlag = -1; 29 } 30 for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0'); 31 ungetc(x, stdin); 32 u *= aFlag; 33 return true; 34 } 35 36 typedef class Edge{ 37 public: 38 int end; 39 int next; 40 int w; 41 Edge(const int end = 0, const int next = 0, const int w = 0):end(end), next(next), w(w){ } 42 }Edge; 43 44 typedef class MapManager{ 45 public: 46 int ce; 47 Edge* edges; 48 int* h; 49 MapManager():ce(0), edges(NULL), h(NULL){ } 50 MapManager(int points, int limit):ce(0){ 51 h = new int[(const int)(points + 1)]; 52 edges = new Edge[(const int)(limit + 1)]; 53 memset(h, 0, sizeof(int) * (points + 1)); 54 } 55 inline void addEdge(int from, int end, int w){ 56 edges[++ce] = Edge(end, h[from], w); 57 h[from] = ce; 58 } 59 inline void addDoubleEdge(int from, int end, int w){ 60 addEdge(from, end, w); 61 addEdge(end, from, w); 62 } 63 Edge& operator [](int pos){ 64 return edges[pos]; 65 } 66 }MapManager; 67 68 #define m_begin(g, i) (g).h[(i)] 69 70 int n, m, st; 71 MapManager g; 72 int* copytime; 73 74 inline void init(){ 75 readInteger(n); 76 readInteger(m); 77 readInteger(st); 78 copytime = new int[(const int)(n + 1)]; 79 g = MapManager(n, 2 * m); 80 for(int i = 1; i <= n; i++) 81 readInteger(copytime[i]); 82 for(int i = 1, a, b, c; i <= m; i++){ 83 readInteger(a); 84 readInteger(b); 85 readInteger(c); 86 g.addDoubleEdge(a, b, c); 87 } 88 } 89 90 queue<int> que; 91 int* f; 92 boolean* visited; 93 void spfa(){ 94 visited = new boolean[(const int)(n + 1)]; 95 f = new int[(const int)(n + 1)]; 96 memset(visited, false, sizeof(boolean) * (n + 1)); 97 memset(f, 0x7f, sizeof(int) * (n + 1)); 98 que.push(st); 99 visited[st] = true; 100 f[st] = copytime[st]; 101 while(!que.empty()){ 102 int e = que.front(); 103 que.pop(); 104 visited[e] = false; 105 for(int i = m_begin(g, e); i != 0; i = g[i].next){ 106 int& eu = g[i].end; 107 if(f[e] + g[i].w + copytime[eu] < f[eu]){ 108 f[eu] = f[e] + copytime[eu] + g[i].w; 109 if(!visited[eu]){ 110 visited[eu] = true; 111 que.push(eu); 112 } 113 } 114 } 115 } 116 } 117 118 inline void solve(){ 119 spfa(); 120 int result = 0; 121 for(int i = 1; i <= n; i++) 122 if(f[i] != 0x7f7f7f7f) 123 smax(result, f[i]); 124 else{ 125 printf("-1"); 126 return; 127 } 128 printf("%d", result); 129 } 130 131 int main(){ 132 freopen("book.in", "r", stdin); 133 freopen("book.out", "w", stdout); 134 init(); 135 solve(); 136 return 0; 137 }
首先用bfs把联通块求出来。然后给每个联通块附一个编号,接着按这个编号排序。(分出了所有联通块)
弄出来然后就可以考虑dp。用f[i][j][k]来表示第i个教研室,选单个还是多个(用j来表示),预算为k的最大精彩程度。(差点忘了这个科室什么都不选的情况,不然AK就没了)。于是可以得出dp方程f[i][j][k] = max{f[i - 1][0/1][k - ts[index].cost], f[i - 1][0/1][k]}(然而第二维貌似不需要,因为是从上一个阶段转移来的,所以不会出现选了一个人又选了这个科室的情况)。
Code
1 #include<iostream> 2 #include<fstream> 3 #include<sstream> 4 #include<cstdio> 5 #include<cstdlib> 6 #include<cstring> 7 #include<ctime> 8 #include<cctype> 9 #include<cmath> 10 #include<algorithm> 11 #include<stack> 12 #include<queue> 13 #include<set> 14 #include<map> 15 #include<vector> 16 using namespace std; 17 typedef bool boolean; 18 #define smin(a, b) (a) = min((a), (b)) 19 #define smax(a, b) (a) = max((a), (b)) 20 template<typename T> 21 inline boolean readInteger(T& u){ 22 char x; 23 int aFlag = 1; 24 while(!isdigit((x = getchar())) && x != '-' && x != -1); 25 if(x == -1) return false; 26 if(x == '-'){ 27 x = getchar(); 28 aFlag = -1; 29 } 30 for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0'); 31 ungetc(x, stdin); 32 u *= aFlag; 33 return true; 34 } 35 36 typedef class Edge{ 37 public: 38 int end; 39 int next; 40 Edge(const int end = 0, const int next = 0):end(end), next(next){ } 41 }Edge; 42 43 typedef class MapManager{ 44 public: 45 int ce; 46 Edge* edges; 47 int* h; 48 MapManager():ce(0), edges(NULL), h(NULL){ } 49 MapManager(int points, int limit):ce(0){ 50 h = new int[(const int)(points + 1)]; 51 edges = new Edge[(const int)(limit + 1)]; 52 memset(h, 0, sizeof(int) * (points + 1)); 53 } 54 inline void addEdge(int from, int end){ 55 edges[++ce] = Edge(end, h[from]); 56 h[from] = ce; 57 } 58 inline void addDoubleEdge(int from, int end){ 59 addEdge(from, end); 60 addEdge(end, from); 61 } 62 Edge& operator [](int pos){ 63 return edges[pos]; 64 } 65 }MapManager; 66 67 #define m_begin(g, i) (g).h[(i)] 68 69 template<typename T> 70 class Matrix{ 71 public: 72 T *list; 73 int lines; 74 int col; 75 Matrix():col(0), lines(0), list(NULL){ } 76 Matrix(int col, int lines):col(col), lines(lines){ 77 list = new T[(col * lines)]; 78 } 79 T* operator [](int pos){ 80 return &list[pos * lines]; 81 } 82 }; 83 84 #define matset(a, i, s) memset((a).list, (i), (s) * (a).lines * (a).col) 85 86 typedef class Teacher{ 87 public: 88 int cost; 89 int value; 90 int belong; 91 Teacher(const int cost = 0, const int value = 0, const int belong = 0):cost(cost), value(value), belong(belong){ } 92 boolean operator < (Teacher another) const{ 93 return belong < another.belong; 94 } 95 }Teacher; 96 97 int n, m, w; 98 Teacher* ts; 99 MapManager g; 100 101 inline void init(){ 102 readInteger(n); 103 readInteger(m); 104 readInteger(w); 105 ts = new Teacher[(const int)(n + 1)]; 106 g = MapManager(n, 2 * m); 107 for(int i = 1; i <= n; i++) readInteger(ts[i].cost); 108 for(int i = 1; i <= n; i++) readInteger(ts[i].value); 109 for(int i = 1, a, b; i <= m; i++){ 110 readInteger(a); 111 readInteger(b); 112 g.addDoubleEdge(a, b); 113 } 114 } 115 116 int cgroup = 0; 117 boolean *visited; 118 queue<int> que; 119 inline void divs(int s, int id){ 120 visited[s] = true; 121 ts[s].belong = id; 122 que.push(s); 123 while(!que.empty()){ 124 int e = que.front(); 125 que.pop(); 126 for(int i = m_begin(g, e); i != 0; i = g[i].next){ 127 int& eu = g[i].end; 128 if(!visited[eu]){ 129 visited[eu] = true; 130 ts[eu].belong = id; 131 que.push(eu); 132 } 133 } 134 } 135 } 136 137 Matrix<int> f[2]; 138 inline int dp(){ 139 for(int i = 0; i <= 1; i++){ 140 f[i] = Matrix<int>(2, w + 1); 141 } 142 int t = 0, result = 0; 143 memset(f[t ^ 1][0], 0, sizeof(int) * (w + 1)); 144 memset(f[t ^ 1][1], 0, sizeof(int) * (w + 1)); 145 for(int i = 1, j = 1; i <= cgroup; i++){ 146 int sumvalue = 0, sumcost = 0; 147 for(int p = 0; p < 2; p++) 148 memcpy(f[t][p], f[t ^ 1][p], sizeof(int) * (w + 1)); 149 for(; j <= n && ts[j].belong == i; j++){ 150 sumvalue += ts[j].value, sumcost += ts[j].cost; 151 for(int k = w; k >= ts[j].cost; k--){ 152 for(int p = 0; p < 2; p++) 153 smax(f[t][0][k], f[t ^ 1][p][k - ts[j].cost] + ts[j].value); 154 } 155 } 156 for(int k = w; k >= sumcost; k--){ 157 for(int p = 0; p < 2; p++) 158 smax(f[t][1][k], f[t ^ 1][p][k - sumcost] + sumvalue); 159 } 160 t ^= 1; 161 } 162 for(int i = 1; i <= w; i++) 163 for(int j = 0; j < 2; j++) 164 smax(result, f[t ^ 1][j][i]); 165 return result; 166 } 167 168 inline void solve(){ 169 visited = new boolean[(const int)(n + 1)]; 170 memset(visited, false, sizeof(boolean) * (n + 1)); 171 for(int i = 1; i <= n; i++){ 172 if(!visited[i]) 173 divs(i, (cgroup += 1)); 174 } 175 delete[] visited; 176 sort(ts + 1, ts + n + 1); 177 int res = dp(); 178 printf("%d", res); 179 } 180 181 int main(){ 182 freopen("teacher.in", "r", stdin); 183 freopen("teacher.out", "w", stdout); 184 init(); 185 solve(); 186 return 0; 187 }