图论测试 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 }
posted @ 2017-01-17 17:53  阿波罗2003  阅读(334)  评论(1编辑  收藏  举报